From 1996d2f719cad4a07968e9fd40dc1d2a401c0543 Mon Sep 17 00:00:00 2001 From: "Christian P. MOMON" Date: Thu, 8 Aug 2024 17:23:52 +0200 Subject: [PATCH] Refactored hugely hooks, added hook cache and servlet cache. --- src/fr/devinsy/kiss4web/Kiss4web.java | 24 +- .../devinsy/kiss4web/Kiss4webException.java | 71 ++++ src/fr/devinsy/kiss4web/Kiss4webLauncher.java | 14 +- src/fr/devinsy/kiss4web/Kiss4webUtils.java | 4 +- ...ssDispatcherCache2.java => PageCache.java} | 18 +- .../kiss4web/dispatcher/KissDispatcher.java | 209 +++-------- .../dispatcher/KissDispatcherFactory.java | 341 ++--------------- .../dispatcher/KissDispatcherServlet.java | 138 +++++++ .../dispatcher/KissDispatcherUtils.java | 348 +++++++++++++++++- ...DispatcherCache.java => ServletCache.java} | 15 +- .../hooks/ApplicationInitFailedHook.java | 60 +-- .../hooks/ApplicationInitFailedServlet.java | 39 ++ .../dispatcher/hooks/ApplicationInitHook.java | 56 +-- .../hooks/ApplicationInitServlet.java | 39 ++ .../kiss4web/dispatcher/hooks/BlankHook.java | 41 +-- .../dispatcher/hooks/BlankSerlvet.java | 39 ++ .../{StatisticsHook.java => DirectHook.java} | 51 +-- .../dispatcher/hooks/DirectServlet.java | 93 +++++ .../kiss4web/dispatcher/hooks/ErrorHook.java | 64 +--- .../dispatcher/hooks/ErrorServlet.java | 109 ++++++ .../kiss4web/dispatcher/hooks/FatalHook.java | 64 +--- .../dispatcher/hooks/FatalServlet.java | 39 ++ .../kiss4web/dispatcher/hooks/FolderHook.java | 37 +- .../kiss4web/dispatcher/hooks/Hook.java | 37 +- .../kiss4web/dispatcher/hooks/HookCore.java | 26 +- .../dispatcher/hooks/HookRegister.java | 4 +- .../dispatcher/hooks/InitFailedHook.java | 64 +--- .../dispatcher/hooks/InitFailedServlet.java | 39 ++ .../kiss4web/dispatcher/hooks/InitHook.java | 58 +-- .../dispatcher/hooks/InitServlet.java | 39 ++ .../dispatcher/hooks/LongURLHook.java | 35 +- .../dispatcher/hooks/MaintenanceHook.java | 47 +-- .../dispatcher/hooks/MaintenanceServlet.java | 39 ++ .../dispatcher/hooks/RewriteHook.java | 58 +-- .../kiss4web/dispatcher/hooks/RootHook.java | 44 +-- .../dispatcher/hooks/ShortURLHook.java | 45 ++- .../dispatcher/hooks/WebContentHook.java | 43 +-- .../dispatcher/hooks/WebContentServlet.java | 91 +++++ .../kiss4web/dispatcher/hooks/WebInfHook.java | 39 +- .../dispatcher/hooks/WebInfServlet.java | 92 +++++ .../kiss4web/dispatcher/hooks/XHTMLHook.java | 38 +- ...toryTest.java => DispatcherUtilsTest.java} | 20 +- 42 files changed, 1599 insertions(+), 1172 deletions(-) create mode 100644 src/fr/devinsy/kiss4web/Kiss4webException.java rename src/fr/devinsy/kiss4web/{dispatcher/KissDispatcherCache2.java => PageCache.java} (64%) create mode 100644 src/fr/devinsy/kiss4web/dispatcher/KissDispatcherServlet.java rename src/fr/devinsy/kiss4web/dispatcher/{KissDispatcherCache.java => ServletCache.java} (84%) create mode 100644 src/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitFailedServlet.java create mode 100644 src/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitServlet.java create mode 100644 src/fr/devinsy/kiss4web/dispatcher/hooks/BlankSerlvet.java rename src/fr/devinsy/kiss4web/dispatcher/hooks/{StatisticsHook.java => DirectHook.java} (62%) create mode 100644 src/fr/devinsy/kiss4web/dispatcher/hooks/DirectServlet.java create mode 100644 src/fr/devinsy/kiss4web/dispatcher/hooks/ErrorServlet.java create mode 100644 src/fr/devinsy/kiss4web/dispatcher/hooks/FatalServlet.java create mode 100644 src/fr/devinsy/kiss4web/dispatcher/hooks/InitFailedServlet.java create mode 100644 src/fr/devinsy/kiss4web/dispatcher/hooks/InitServlet.java create mode 100644 src/fr/devinsy/kiss4web/dispatcher/hooks/MaintenanceServlet.java create mode 100755 src/fr/devinsy/kiss4web/dispatcher/hooks/WebContentServlet.java create mode 100644 src/fr/devinsy/kiss4web/dispatcher/hooks/WebInfServlet.java rename test/fr/devinsy/kiss4web/dispatcher/{DispatcherFactoryTest.java => DispatcherUtilsTest.java} (78%) diff --git a/src/fr/devinsy/kiss4web/Kiss4web.java b/src/fr/devinsy/kiss4web/Kiss4web.java index 76f095c..5b33026 100644 --- a/src/fr/devinsy/kiss4web/Kiss4web.java +++ b/src/fr/devinsy/kiss4web/Kiss4web.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2013-2023 Christian Pierre MOMON +/* + * Copyright (C) 2013-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -160,7 +160,7 @@ public class Kiss4web this.mode = mode; HookRegister hooks = new HookRegister("Init failed"); hooks.register(new InitFailedHook()); - KissDispatcher.setHookRegister(hooks); + KissDispatcher.instance().setHookRegister(hooks); } } break; @@ -172,7 +172,7 @@ public class Kiss4web this.mode = mode; HookRegister hooks = new HookRegister("Application Init"); hooks.register(new ApplicationInitHook()); - KissDispatcher.setHookRegister(hooks); + KissDispatcher.instance().setHookRegister(hooks); } } break; @@ -184,14 +184,14 @@ public class Kiss4web this.mode = mode; HookRegister hooks = new HookRegister("Application Init failed"); hooks.register(new ApplicationInitFailedHook()); - KissDispatcher.setHookRegister(hooks); + KissDispatcher.instance().setHookRegister(hooks); } } break; case OPEN: { - if ((this.mode == Mode.INIT) || (this.mode == Mode.APP_INIT)) + if ((this.mode == Mode.APP_INIT) || (this.mode == Mode.MAINTENANCE)) { this.mode = mode; @@ -205,7 +205,7 @@ public class Kiss4web hooks.register(new WebContentHook()); hooks.register(new WebInfHook()); - KissDispatcher.setHookRegister(hooks); + KissDispatcher.instance().setHookRegister(hooks); } } break; @@ -217,7 +217,7 @@ public class Kiss4web HookRegister hooks = new HookRegister("Maintenance"); hooks.register(new MaintenanceHook()); - KissDispatcher.setHookRegister(hooks); + KissDispatcher.instance().setHookRegister(hooks); } break; @@ -228,11 +228,15 @@ public class Kiss4web HookRegister hooks = new HookRegister("Fatal"); hooks.register(new FatalHook()); - KissDispatcher.setHookRegister(hooks); + KissDispatcher.instance().setHookRegister(hooks); } break; case CUSTOM: + if ((this.mode == Mode.APP_INIT) || (this.mode == Mode.MAINTENANCE) || (this.mode == Mode.OPEN)) + { + this.mode = mode; + } break; } } @@ -248,7 +252,7 @@ public class Kiss4web if (hooks != null) { this.mode = Mode.CUSTOM; - KissDispatcher.setHookRegister(hooks); + KissDispatcher.instance().setHookRegister(hooks); } } diff --git a/src/fr/devinsy/kiss4web/Kiss4webException.java b/src/fr/devinsy/kiss4web/Kiss4webException.java new file mode 100644 index 0000000..c374633 --- /dev/null +++ b/src/fr/devinsy/kiss4web/Kiss4webException.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2024 Christian Pierre MOMON + * + * This file is part of Kiss4web. + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Kiss4web. If not, see + */ + +package fr.devinsy.kiss4web; + +/** + * The Class Kiss4webException. + */ +public class Kiss4webException extends Exception +{ + private static final long serialVersionUID = -6018571288000296858L; + + /** + * Instantiates a new kiss 4 web exception. + */ + public Kiss4webException() + { + super(); + } + + /** + * Instantiates a new kiss 4 web exception. + * + * @param message + * the message + */ + public Kiss4webException(final String message) + { + super(message); + } + + /** + * Instantiates a new kiss 4 web exception. + * + * @param message + * the message + * @param cause + * the cause + */ + public Kiss4webException(final String message, final Throwable cause) + { + super(message, cause); + } + + /** + * Instantiates a new kiss 4 web exception. + * + * @param cause + * the cause + */ + public Kiss4webException(final Throwable cause) + { + super(cause); + } +} diff --git a/src/fr/devinsy/kiss4web/Kiss4webLauncher.java b/src/fr/devinsy/kiss4web/Kiss4webLauncher.java index eab016f..71eb836 100644 --- a/src/fr/devinsy/kiss4web/Kiss4webLauncher.java +++ b/src/fr/devinsy/kiss4web/Kiss4webLauncher.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2013-2023 Christian Pierre MOMON +/* + * Copyright (C) 2013-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -115,14 +115,4 @@ public class Kiss4webLauncher implements ServletContextListener logger.info("Log initialization done."); } } - - /** - * Launch. - * - * @param context - * the context - */ - public void launch(final ServletContext context) - { - } } diff --git a/src/fr/devinsy/kiss4web/Kiss4webUtils.java b/src/fr/devinsy/kiss4web/Kiss4webUtils.java index 039564a..5d0331c 100644 --- a/src/fr/devinsy/kiss4web/Kiss4webUtils.java +++ b/src/fr/devinsy/kiss4web/Kiss4webUtils.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2021 Christian Pierre MOMON +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * diff --git a/src/fr/devinsy/kiss4web/dispatcher/KissDispatcherCache2.java b/src/fr/devinsy/kiss4web/PageCache.java similarity index 64% rename from src/fr/devinsy/kiss4web/dispatcher/KissDispatcherCache2.java rename to src/fr/devinsy/kiss4web/PageCache.java index e30f96e..437dad8 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/KissDispatcherCache2.java +++ b/src/fr/devinsy/kiss4web/PageCache.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2021 Christian Pierre MOMON +/* + * Copyright (C) 2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with Kiss4web. If not, see */ -package fr.devinsy.kiss4web.dispatcher; +package fr.devinsy.kiss4web; import java.util.HashMap; @@ -24,17 +24,17 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * The Class KissClassCache. + * The Class PageCache. */ -public class KissDispatcherCache2 extends HashMap +public class PageCache extends HashMap { - private static final long serialVersionUID = 2058060444094070931L; - private static Logger logger = LoggerFactory.getLogger(KissDispatcherCache2.class); + private static final long serialVersionUID = 6600633944028794039L; + private static Logger logger = LoggerFactory.getLogger(PageCache.class); /** - * Instantiates a new kiss class cache. + * Instantiates a new kiss page cache. */ - public KissDispatcherCache2() + public PageCache() { super(); } diff --git a/src/fr/devinsy/kiss4web/dispatcher/KissDispatcher.java b/src/fr/devinsy/kiss4web/dispatcher/KissDispatcher.java index 1957156..eea3912 100755 --- a/src/fr/devinsy/kiss4web/dispatcher/KissDispatcher.java +++ b/src/fr/devinsy/kiss4web/dispatcher/KissDispatcher.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2023 Christian Pierre MOMON +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,19 +18,17 @@ */ package fr.devinsy.kiss4web.dispatcher; -import java.io.IOException; -import java.util.Date; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import fr.devinsy.kiss4web.dispatcher.hooks.ErrorServlet; import fr.devinsy.kiss4web.dispatcher.hooks.Hook; import fr.devinsy.kiss4web.dispatcher.hooks.HookRegister; import fr.devinsy.kiss4web.dispatcher.hooks.InitHook; +import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; /** * The Class KissDispatcher. @@ -39,172 +37,75 @@ import jakarta.servlet.http.HttpServletResponse; * (). * */ -public class KissDispatcher extends HttpServlet +public class KissDispatcher { - private static final long serialVersionUID = -3471226305721330069L; private static final Logger logger = LoggerFactory.getLogger(KissDispatcher.class); public static final int DEFAULT_CACHE_AGE = 2 * 60 * 60; - private static HookRegister hookRegister = new HookRegister("Init").register(new InitHook()); + private static KissDispatcher instance = new KissDispatcher(); + + private HookRegister hookRegister; + + // Pathinfo -> Servlet. + private ServletCache cache; /** * Instantiates a new kiss dispatcher. */ - public KissDispatcher() + private KissDispatcher() { + this.cache = new ServletCache(); + this.hookRegister = new HookRegister("Init").register(new InitHook()); } /** - *
-     * "/" => "Index_xhtml"
-     * "/good/" => "good.Good_xhtml"
-     * "/good/morning.xhtml" => "good.Morning_xhtml"
-     * "/good/morning_girl.xhtml" => "good.Morning_girl_xhtml"
-     * "/good/morning-123.xhtml" => "good.Morning_xhtml" ('123' is detected as a parameter, it will be
-     * decoded in the class called later).
-     * "/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).
-     * 
+ * Provide servlet. * + * @param config + * the config * @param request * the request - * @param response - * the response - * @throws IOException - * Signals that an I/O exception has occurred. - * @throws ServletException - * the servlet exception + * @return the http servlet */ - public void dispatch(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + public HttpServlet provideServlet(final ServletConfig config, final HttpServletRequest request) { - long startTime = new Date().getTime(); + HttpServlet result; - request.setCharacterEncoding("UTF-8"); - - logger.info("=================================================="); - logger.info("getContextPath=[" + request.getContextPath() + "]"); - logger.info("getPathInfo=[" + request.getPathInfo() + "]"); - logger.info("getPathTranslated=[" + request.getPathTranslated() + "]"); - logger.info("getQueryString=[" + request.getQueryString() + "]"); - logger.info("getRequestURI=[" + request.getRequestURI() + "]"); - logger.info("getRequestURL=[" + request.getRequestURL() + "]"); - logger.info("getServletPath=[" + request.getServletPath() + "]"); - - // - /* - * In past, possibility to use the servlet path was enable. It is too - * complexe, not kiss mind. - * - * String path; - * if (request.getPathInfo() == null) - * { - * // web.xml url-pattern= *.xhtml - * path = request.getServletPath(); - * } - * else - * { - * // web.xml url-pattern = - * path = request.getPathInfo(); - * } - * - * https://issues.apache.org/bugzilla/show_bug.cgi?id=11318 - * A number of features have been introduced in later versions of Tomcat - * that relate to URI encoding. This includes a URIEncoding attribute - * on the Coyote HTTP/1.1 connector which defaults to ISO-8859-1. - * - * According to the servlet specification: - * HttpServletRequest.getPathInfo() should be decoded by the web container; - * HttpServletRequest.getRequestURI() should not be decoded by the web container. - * - * - * http://stackoverflow.com/questions/15278512/safe-html-form-accept-charset/15587140#15587140 - * The standard URL encoding must use UTF-8 yet servlets not only default to ISO-8859-1 but don't offer - * any way to change that with code. - * Sure you can req.setRequestEncoding("UTF-8") before you read anything, but for some ungodly reason this only affects request body, - * not query string parameters. There is nothing in the servlet request interface to specify the encoding used for query string parameters. - * Using ISO-8859-1 in your form is a hack. Using this ancient encoding will cause more problems than solve for sure. - * Especially since browsers do not support ISO-8859-1 and always treat it as Windows-1252. Whereas servlets treat ISO-8859-1 as ISO-8859-1, - * so you will be screwed beyond belief if you go with this. - * To change this in Tomcat for example, you can use the URIEncoding attribute in your element: - * - * - * If you don't use a container that has these settings, can't change its settings or some other issue, - * you can still make it work because ISO-8859-1 decoding retains full information from the original binary. - * String correct = new String(request.getParameter("test").getBytes("ISO-8859-1"), "UTF-8") - * - * - * http://tomcat.apache.org/tomcat-5.5-doc/config/http.html - * URIEncoding - * This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. - * If not specified, ISO-8859-1 will be used. - * - */ - // String urlPath = request.getPathInfo(); - - // Search a matching catcher. - Hook hook = hookRegister.getMatching(this.getServletContext(), request); - if (hook == null) + try { - logger.info("Request not satisfied [" + request.getPathInfo() + "]"); - response.sendError(HttpServletResponse.SC_NOT_FOUND); + result = this.cache.get(request.getPathInfo()); + if (result == null) + { + logger.debug("PathInfo is NOT matching servlet cache."); + Hook hook = this.hookRegister.getMatching(config.getServletContext(), request); + if (hook == null) + { + result = new ErrorServlet("Hook not found."); + } + else + { + logger.debug("Hook matching: {}", hook.getClass().getCanonicalName()); + String servletClassName = hook.getServletClassName(config, request); + + Class servletClass = KissDispatcherUtils.pickServletClass(servletClassName); + + result = KissDispatcherFactory.instance().provideServlet(config, servletClass); + this.cache.put(request.getPathInfo(), result); + } + } + else + { + logger.debug("PathInfo is matching servlet cache [{}]", result.getClass().getCanonicalName()); + } } - else + catch (IllegalArgumentException | SecurityException | ServletException exception) { - logger.info("Catch found for {}", hook.getClass().getSimpleName()); - hook.process(this.getServletConfig(), this.getServletContext(), request, response); + result = new ErrorServlet("Error instanciating servlet.", exception); } // - long endTime = new Date().getTime(); - logger.debug("TIME: {}ms {}", endTime - startTime, request.getPathInfo()); - } - - /** - * {@inheritDoc} - */ - @Override - public void doDelete(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException - { - dispatch(request, response); - } - - /** - * {@inheritDoc} - */ - @Override - public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException - { - dispatch(request, response); - } - - /** - * {@inheritDoc} - */ - @Override - public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException - { - dispatch(request, response); - } - - /** - * {@inheritDoc} - */ - @Override - public void doPut(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException - { - dispatch(request, response); - } - - /** - * {@inheritDoc} - */ - @Override - public void init() throws ServletException - { - super.init(); - - System.out.println("KissDispatcher INIT."); + return result; } /** @@ -213,14 +114,24 @@ public class KissDispatcher extends HttpServlet * @param register * the new hook register */ - public static void setHookRegister(final HookRegister register) + public void setHookRegister(final HookRegister register) { if ((register != null) && (!register.isEmpty())) { HookRegister target = new HookRegister(register.getName()); target.registerAll(register); - hookRegister = target; + this.hookRegister = target; KissDispatcherFactory.instance().clearCache(); } } + + /** + * Instance. + * + * @return the kiss dispatcher + */ + public static KissDispatcher instance() + { + return instance; + } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/KissDispatcherFactory.java b/src/fr/devinsy/kiss4web/dispatcher/KissDispatcherFactory.java index 93ef8f1..4ecef77 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/KissDispatcherFactory.java +++ b/src/fr/devinsy/kiss4web/dispatcher/KissDispatcherFactory.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2023 Christian Pierre MOMON +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,17 +18,12 @@ */ package fr.devinsy.kiss4web.dispatcher; -import java.io.IOException; -import java.io.PrintWriter; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; /** * A factory for creating KissDispatcher objects. @@ -41,16 +36,20 @@ public class KissDispatcherFactory private static final KissDispatcherFactory instance = new KissDispatcherFactory(); } - private static Logger logger = LoggerFactory.getLogger(KissDispatcherFactory.class); + static Logger logger = LoggerFactory.getLogger(KissDispatcherFactory.class); - private KissDispatcherCache cache; + /* + * Need to avoid servlet duplication when more than pathinfo is matching a servlet. + * ClassPath -> Servlet. + */ + private ServletCache cache; /** * Instantiates a new kiss dispatcher factory. */ private KissDispatcherFactory() { - this.cache = new KissDispatcherCache(); + this.cache = new ServletCache(); } /** @@ -62,126 +61,32 @@ public class KissDispatcherFactory } /** - * Dispatch to servlet. + * Provide servlet. * - * @param servletConfig - * the servlet config + * @param config + * the config * @param request * the request - * @param response - * the response - * @param urlPath - * the url path - * @throws IOException - * Signals that an I/O exception has occurred. + * @return the http servlet * @throws ServletException - * the servlet exception */ - public void dispatchPathToServlet(final ServletConfig servletConfig, final HttpServletRequest request, final HttpServletResponse response, - final String urlPath) throws IOException, ServletException + public HttpServlet provideServlet(final ServletConfig config, final Class servletClass) throws ServletException { - // Get the servlet. - HttpServlet servlet = this.cache.get(urlPath); - if (servlet == null) + HttpServlet result; + + if ((config == null) || (servletClass == null)) { - String className = translateToClassName(urlPath); - logger.info("className=[" + 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) - { - logger.info("Trying with underscore conservative."); - className = translateToClassNameAlternative(urlPath); - logger.info("className=[" + className + "]"); - servlet = KissDispatcherUtils.instanciateServlet("website." + className); - } - - if (servlet != null) - { - servlet.init(servletConfig); - this.cache.put(urlPath, servlet); - } + throw new ServletException("Null parameter detected calling KDF.provideServlet method."); } else { - logger.info("Class cache MATCHED."); - } - - // Serve the servlet. - if (servlet == null) - { - response.setContentType("text/html"); - PrintWriter out = response.getWriter(); - - out.println(""); - out.println("Unknown page."); - out.println(""); - - out.close(); - } - else - { - servlet.service(request, response); - } - } - - /** - * Checks if is available class. - * - * @param className - * the class name - * @return true, if is available class - */ - private boolean isAvailableClass(final String className) - { - boolean result; - - try - { - Class servletClass = (Class) Class.forName(className); - result = true; - } - catch (java.lang.ClassNotFoundException exception) - { - result = false; - } - - // - return result; - } - - /** - * Checks if is available path. - * - * @param urlPath - * the url path - * @return true, if is available path - */ - public boolean isAvailablePath(final String urlPath) - { - boolean result; - - if (this.cache.containsKey(urlPath)) - { - result = true; - } - else - { - String className = "website." + translateToClassName(urlPath); - if (isAvailableClass(className) || isAvailableClass(className.replaceAll("Xhtml$", "Page"))) + String className = servletClass.getCanonicalName(); + result = this.cache.get(className); + if (result == null) { - result = true; - } - else - { - result = false; + result = KissDispatcherUtils.instanciateServlet(className); + result.init(config); + this.cache.put(className, result); } } @@ -198,202 +103,4 @@ public class KissDispatcherFactory { return SingletonHolder.instance; } - - /** - * Translate to class name. - * - *
-     * "/" => "IndexXhtml"
-     * "/good/" => "good.IndexXhtml"
-     * "/good/morning.xhtml" => "good.MorningXhtml"
-     * "/good/morning_girl.xhtml" => "good.MorningGirlXhtml"
-     * "/good/morning-girl.xhtml" => "good.MorningGirlXhtml"
-     * 
- * - * @param urlPath - * the url path - * @return the string - */ - public static String translateToClassName(final String urlPath) - { - String result; - - if (urlPath == null) - { - result = null; - } - else - { - if (urlPath.length() == 1) - { - result = "IndexXhtml"; - } - else if (urlPath.endsWith("/")) - { - StringBuffer buffer = new StringBuffer(urlPath.length() + 50); - for (int index = 1; index < urlPath.length(); index++) - { - char letter = urlPath.charAt(index); - - if (letter == '/') - { - buffer.append('.'); - } - else - { - buffer.append(letter); - } - } - buffer.append("IndexXhtml"); - - result = buffer.toString(); - } - else - { - int lastToken = urlPath.lastIndexOf('/'); - - StringBuffer buffer = new StringBuffer(urlPath.length()); - for (int index = 1; index <= lastToken; index++) - { - char letter = urlPath.charAt(index); - - if (letter == '/') - { - buffer.append('.'); - } - else - { - buffer.append(letter); - } - } - - 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; - } - - /** - * Translate to class name. - * - *
-     * "/" => "Index_xhtml"
-     * "/good/" => "good.Index_xhtml"
-     * "/good/morning.xhtml" => "good.MorningXhtml"
-     * "/good/morning_girl.xhtml" => "good.Morning-Girl_xhtml"
-     * "/good/morning-girl.xhtml" => "good.Morning_Girl_xhtml"
-     * 
- * - * @param urlPath - * the url path - * @return the string - */ - public static String translateToClassNameAlternative(final String urlPath) - { - String result; - - if (urlPath == null) - { - result = null; - } - else - { - if (urlPath.length() == 1) - { - result = "IndexXhtml"; - } - else if (urlPath.endsWith("/")) - { - StringBuffer buffer = new StringBuffer(urlPath.length() + 50); - for (int index = 1; index < urlPath.length(); index++) - { - char letter = urlPath.charAt(index); - - if (letter == '/') - { - buffer.append('.'); - } - else - { - buffer.append(letter); - } - } - buffer.append(".Index_xhtml"); - - result = buffer.toString(); - } - else - { - int lastToken = urlPath.lastIndexOf('/'); - - StringBuffer buffer = new StringBuffer(urlPath.length()); - for (int index = 1; index <= lastToken; index++) - { - char letter = urlPath.charAt(index); - - if (letter == '/') - { - buffer.append('.'); - } - else - { - buffer.append(letter); - } - } - - if (lastToken + 1 < urlPath.length()) - { - buffer.append(Character.toUpperCase(urlPath.charAt(lastToken + 1))); - } - - for (int index = lastToken + 2; index < urlPath.length(); index++) - { - char letter = urlPath.charAt(index); - - if (letter == '.') - { - buffer.append('_'); - } - else - { - buffer.append(letter); - } - } - - result = buffer.toString(); - } - } - - logger.info(urlPath + " -> " + result); - - // - return result; - } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/KissDispatcherServlet.java b/src/fr/devinsy/kiss4web/dispatcher/KissDispatcherServlet.java new file mode 100644 index 0000000..8478892 --- /dev/null +++ b/src/fr/devinsy/kiss4web/dispatcher/KissDispatcherServlet.java @@ -0,0 +1,138 @@ +/** + * Copyright (C) 2006-2024 Christian Pierre MOMON + * + * This file is part of Kiss4web. + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Kiss4web. If not, see + */ +package fr.devinsy.kiss4web.dispatcher; + +import java.io.IOException; +import java.util.Date; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * The Class KissDispatcher. + * + * According that URL is under UTF-8 format. Set Tomcat connector if needs + * (). + * + */ +public class KissDispatcherServlet extends HttpServlet +{ + private static final long serialVersionUID = -7278690604864844533L; + private static final Logger logger = LoggerFactory.getLogger(KissDispatcherServlet.class); + + /** + * Instantiates a new kiss dispatcher. + */ + public KissDispatcherServlet() + { + } + + /** + * {@inheritDoc} + */ + @Override + public void init() throws ServletException + { + super.init(); + + System.out.println("KissDispatcher INIT."); + } + + /** + * {@inheritDoc} + */ + @Override + public void service(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + { + long startTime = new Date().getTime(); + + request.setCharacterEncoding("UTF-8"); + + logger.info("=================================================="); + logger.info("getContextPath=[" + request.getContextPath() + "]"); + logger.info("getPathInfo=[" + request.getPathInfo() + "]"); + logger.info("getPathTranslated=[" + request.getPathTranslated() + "]"); + logger.info("getQueryString=[" + request.getQueryString() + "]"); + logger.info("getRequestURI=[" + request.getRequestURI() + "]"); + logger.info("getRequestURL=[" + request.getRequestURL() + "]"); + logger.info("getServletPath=[" + request.getServletPath() + "]"); + + /* + * In past, possibility to use the servlet path was enable. It is too + * complexe, not kiss mind. + * + * String path; + * if (request.getPathInfo() == null) + * { + * // web.xml url-pattern= *.xhtml + * path = request.getServletPath(); + * } + * else + * { + * // web.xml url-pattern = + * path = request.getPathInfo(); + * } + * + * https://issues.apache.org/bugzilla/show_bug.cgi?id=11318 + * A number of features have been introduced in later versions of Tomcat + * that relate to URI encoding. This includes a URIEncoding attribute + * on the Coyote HTTP/1.1 connector which defaults to ISO-8859-1. + * + * According to the servlet specification: + * HttpServletRequest.getPathInfo() should be decoded by the web container; + * HttpServletRequest.getRequestURI() should not be decoded by the web container. + * + * + * http://stackoverflow.com/questions/15278512/safe-html-form-accept-charset/15587140#15587140 + * The standard URL encoding must use UTF-8 yet servlets not only default to ISO-8859-1 but don't offer + * any way to change that with code. + * Sure you can req.setRequestEncoding("UTF-8") before you read anything, but for some ungodly reason this only affects request body, + * not query string parameters. There is nothing in the servlet request interface to specify the encoding used for query string parameters. + * Using ISO-8859-1 in your form is a hack. Using this ancient encoding will cause more problems than solve for sure. + * Especially since browsers do not support ISO-8859-1 and always treat it as Windows-1252. Whereas servlets treat ISO-8859-1 as ISO-8859-1, + * so you will be screwed beyond belief if you go with this. + * To change this in Tomcat for example, you can use the URIEncoding attribute in your element: + * + * + * If you don't use a container that has these settings, can't change its settings or some other issue, + * you can still make it work because ISO-8859-1 decoding retains full information from the original binary. + * String correct = new String(request.getParameter("test").getBytes("ISO-8859-1"), "UTF-8") + * + * + * http://tomcat.apache.org/tomcat-5.5-doc/config/http.html + * URIEncoding + * This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. + * If not specified, ISO-8859-1 will be used. + * + */ + // String urlPath = request.getPathInfo(); + + HttpServlet servlet = KissDispatcher.instance().provideServlet(this.getServletConfig(), request); + servlet.service(request, response); + + // + long endTime = new Date().getTime(); + logger.debug("TIME: {}ms {}", endTime - startTime, request.getPathInfo()); + } +} \ No newline at end of file diff --git a/src/fr/devinsy/kiss4web/dispatcher/KissDispatcherUtils.java b/src/fr/devinsy/kiss4web/dispatcher/KissDispatcherUtils.java index 0f65414..bddff56 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/KissDispatcherUtils.java +++ b/src/fr/devinsy/kiss4web/dispatcher/KissDispatcherUtils.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2023 Christian Pierre MOMON +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -25,6 +25,7 @@ import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; import java.util.Date; import java.util.Enumeration; +import java.util.Objects; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,7 +50,7 @@ public class KissDispatcherUtils INLINE } - private static Logger logger = LoggerFactory.getLogger(KissDispatcherUtils.class); + static Logger logger = LoggerFactory.getLogger(KissDispatcherUtils.class); /** * Builds the class name. @@ -141,6 +142,7 @@ public class KissDispatcherUtils * @throws ServletException * the servlet exception */ + @Deprecated public static void dispatchToServlet(final ServletConfig servletConfig, final HttpServletRequest request, final HttpServletResponse response, final String className) throws IOException, ServletException { @@ -203,18 +205,18 @@ public class KissDispatcherUtils /** * Instanciate servlet. * - * @param classPathname + * @param className * the class pathname * @return the http servlet */ - public static HttpServlet instanciateServlet(final String classPathname) + public static HttpServlet instanciateServlet(final String className) { HttpServlet result; Class servletClass = null; try { - servletClass = (Class) Class.forName(classPathname); + servletClass = (Class) Class.forName(className); } catch (java.lang.ClassNotFoundException exception) { @@ -224,7 +226,7 @@ public class KissDispatcherUtils if (servletClass == null) { result = null; - logger.warn("unknown page: [{}]", classPathname); + logger.warn("unknown page: [{}]", className); } else { @@ -235,17 +237,17 @@ public class KissDispatcherUtils } catch (java.lang.InstantiationException exception) { - logger.error("Can't instanciate servlet (" + classPathname + ")", exception); + logger.error("Can't instanciate servlet (" + className + ")", exception); result = null; } catch (java.lang.IllegalAccessException exception) { - logger.error("(2) Can't instanciate servlet (" + classPathname + ")", exception); + logger.error("(2) Can't instanciate servlet (" + className + ")", exception); result = null; } catch (IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException exception) { - logger.error("(3) Can't instanciate servlet (" + classPathname + ")", exception); + logger.error("(3) Can't instanciate servlet (" + className + ")", exception); result = null; } } @@ -254,6 +256,54 @@ public class KissDispatcherUtils return result; } + /** + * Checks if is available path. + * + * @param urlPath + * the url path + * @return true, if is available path + */ + public static boolean isAvailablePath(final String path) + { + boolean result; + + if (pickServletClass(path) == null) + { + result = false; + } + else + { + result = true; + } + + // + return result; + } + + /** + * Path to class. + * + * @param className + * the class pathname + * @return the class + */ + public static Class nameToClass(final String className) + { + Class result; + + try + { + result = Class.forName(className); + } + catch (java.lang.ClassNotFoundException exception) + { + result = null; + } + + // + return result; + } + /** * Convert a path in a class name, using kiss conventions. * @@ -382,6 +432,39 @@ public class KissDispatcherUtils return result; } + /** + * Path to servlet class. + * + * @param className + * the class pathname + * @return the class + */ + public static Class pickServletClass(final String className) + { + Class result; + + // String className = KissDispatcherUtils.translateToClassName(path); + logger.info("className=[{}]", className); + + result = nameToClass(className); + if (result == null) + { + logger.info("Trying with Page suffix."); + result = nameToClass(className.replaceAll("Xhtml$", "Page")); + } + + if (result == null) + { + logger.info("Trying with Do suffix."); + result = nameToClass(className.replaceAll("Xhtml$", "Do")); + } + + logger.debug("servletClass={}", result); + + // + return result; + } + /** * Return attachment file. * @@ -416,6 +499,29 @@ public class KissDispatcherUtils public static void returnFile(final HttpServletResponse response, final File file, final String mimeType, final ContentDispositionType contentDisposition) throws IOException { + returnFile(response, file, null, mimeType, contentDisposition); + } + + /** + * Return file. + * + * @param response + * the response + * @param file + * the file + * @param targetFilename + * the target filename, in case the name of file is not the one + * intended, if null then the file name is used + * @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 targetFilename, final String mimeType, + final ContentDispositionType contentDisposition) throws IOException + { if ((file == null) || (!file.exists())) { @@ -443,7 +549,9 @@ public class KissDispatcherUtils { contentDispositionToken = "inline"; } - response.setHeader("Content-Disposition", contentDispositionToken + "; filename=\"" + file.getName() + "\""); + + response.setHeader("Content-Disposition", + contentDispositionToken + "; filename=\"" + Objects.toString(targetFilename, file.getName()) + "\""); response.setDateHeader("Expires", new Date().getTime() + KissDispatcher.DEFAULT_CACHE_AGE * 1000); response.setHeader("Cache-Control", "max-age=" + KissDispatcher.DEFAULT_CACHE_AGE); @@ -585,6 +693,26 @@ public class KissDispatcherUtils returnFile(response, file, mimeType, ContentDispositionType.INLINE); } + /** + * Return inline file. + * + * @param response + * the response + * @param file + * the file + * @param targetFilename + * the target filename + * @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 targetFilename, final String mimeType) + throws IOException + { + returnFile(response, file, targetFilename, mimeType, ContentDispositionType.INLINE); + } + /** * Show parameters. * @@ -622,4 +750,202 @@ public class KissDispatcherUtils // return result; } + + /** + * Translate to class name. + * + *
+     * "/" => "IndexXhtml"
+     * "/good/" => "good.IndexXhtml"
+     * "/good/morning.xhtml" => "good.MorningXhtml"
+     * "/good/morning_girl.xhtml" => "good.MorningGirlXhtml"
+     * "/good/morning-girl.xhtml" => "good.MorningGirlXhtml"
+     * 
+ * + * @param urlPath + * the url path + * @return the string + */ + public static String translateToClassName(final String urlPath) + { + String result; + + if (urlPath == null) + { + result = null; + } + else + { + if (urlPath.length() == 1) + { + result = "IndexXhtml"; + } + else if (urlPath.endsWith("/")) + { + StringBuffer buffer = new StringBuffer(urlPath.length() + 50); + for (int index = 1; index < urlPath.length(); index++) + { + char letter = urlPath.charAt(index); + + if (letter == '/') + { + buffer.append('.'); + } + else + { + buffer.append(letter); + } + } + buffer.append("IndexXhtml"); + + result = buffer.toString(); + } + else + { + int lastToken = urlPath.lastIndexOf('/'); + + StringBuffer buffer = new StringBuffer(urlPath.length()); + for (int index = 1; index <= lastToken; index++) + { + char letter = urlPath.charAt(index); + + if (letter == '/') + { + buffer.append('.'); + } + else + { + buffer.append(letter); + } + } + + 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(); + } + } + + KissDispatcherFactory.logger.info(urlPath + " -> " + result); + + // + return result; + } + + /** + * Translate to class name. + * + *
+     * "/" => "Index_xhtml"
+     * "/good/" => "good.Index_xhtml"
+     * "/good/morning.xhtml" => "good.MorningXhtml"
+     * "/good/morning_girl.xhtml" => "good.Morning-Girl_xhtml"
+     * "/good/morning-girl.xhtml" => "good.Morning_Girl_xhtml"
+     * 
+ * + * @param urlPath + * the url path + * @return the string + */ + public static String translateToClassNameAlternative(final String urlPath) + { + String result; + + if (urlPath == null) + { + result = null; + } + else + { + if (urlPath.length() == 1) + { + result = "IndexXhtml"; + } + else if (urlPath.endsWith("/")) + { + StringBuffer buffer = new StringBuffer(urlPath.length() + 50); + for (int index = 1; index < urlPath.length(); index++) + { + char letter = urlPath.charAt(index); + + if (letter == '/') + { + buffer.append('.'); + } + else + { + buffer.append(letter); + } + } + buffer.append(".Index_xhtml"); + + result = buffer.toString(); + } + else + { + int lastToken = urlPath.lastIndexOf('/'); + + StringBuffer buffer = new StringBuffer(urlPath.length()); + for (int index = 1; index <= lastToken; index++) + { + char letter = urlPath.charAt(index); + + if (letter == '/') + { + buffer.append('.'); + } + else + { + buffer.append(letter); + } + } + + if (lastToken + 1 < urlPath.length()) + { + buffer.append(Character.toUpperCase(urlPath.charAt(lastToken + 1))); + } + + for (int index = lastToken + 2; index < urlPath.length(); index++) + { + char letter = urlPath.charAt(index); + + if (letter == '.') + { + buffer.append('_'); + } + else + { + buffer.append(letter); + } + } + + result = buffer.toString(); + } + } + + KissDispatcherFactory.logger.info(urlPath + " -> " + result); + + // + return result; + } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/KissDispatcherCache.java b/src/fr/devinsy/kiss4web/dispatcher/ServletCache.java similarity index 84% rename from src/fr/devinsy/kiss4web/dispatcher/KissDispatcherCache.java rename to src/fr/devinsy/kiss4web/dispatcher/ServletCache.java index 32ee7dd..1ecfcbe 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/KissDispatcherCache.java +++ b/src/fr/devinsy/kiss4web/dispatcher/ServletCache.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2023 Christian Pierre MOMON +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -26,17 +26,17 @@ import org.slf4j.LoggerFactory; import jakarta.servlet.http.HttpServlet; /** - * The Class KissDispatcherCache. + * The Class ServletCache. */ -public class KissDispatcherCache extends HashMap +public class ServletCache extends HashMap { private static final long serialVersionUID = -7727974577347443504L; - private static Logger logger = LoggerFactory.getLogger(KissDispatcherCache.class); + private static Logger logger = LoggerFactory.getLogger(ServletCache.class); /** * Instantiates a new kiss dispatcher cache. */ - public KissDispatcherCache() + public ServletCache() { super(); } @@ -53,13 +53,14 @@ public class KissDispatcherCache extends HashMap HttpServlet result; boolean ended = false; + int index = 0; result = null; while (!ended) { if (index < path.length) { - result = get(path); + result = super.get(path[index]); if (result == null) { index += 1; diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitFailedHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitFailedHook.java index 4a2ec7b..c87aab7 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitFailedHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitFailedHook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2018-2023 Christian Pierre MOMON +/* + * Copyright (C) 2018-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,69 +18,21 @@ */ package fr.devinsy.kiss4web.dispatcher.hooks; -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jakarta.servlet.ServletConfig; -import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - /** - * The Class InitHook. + * The Class ApplicationInitFailedHook. */ -public class ApplicationInitFailedHook extends HookCore +public class ApplicationInitFailedHook extends DirectHook { private static Logger logger = LoggerFactory.getLogger(ApplicationInitFailedHook.class); /** - * Instantiates a new inits the hook. + * Instantiates a new application init failed hook. */ public ApplicationInitFailedHook() { - super(); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean matches(final ServletContext servletContext, final HttpServletRequest request) - { - boolean result; - - result = true; - - // - return result; - } - - /** - * {@inheritDoc} - */ - @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException, ServletException - { - logger.debug("Doing catch {}.", this.getClass().getName()); - - String path = servletContext.getRealPath("/") + request.getPathInfo(); - logger.info("path=[{}]", path); - - // Get page. - URL url = Hook.class.getResource("/fr/devinsy/kiss4web/dispatcher/hooks/applicationInitFailed.xhtml"); - String xhtml = IOUtils.toString(url, StandardCharsets.UTF_8); - - // Display page. - response.setContentType("application/xhtml+xml; charset=UTF-8"); - response.getWriter().println(xhtml); - - logger.info("Application Init Failed page returned."); + super("/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitFailedServlet"); } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitFailedServlet.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitFailedServlet.java new file mode 100644 index 0000000..21468b9 --- /dev/null +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitFailedServlet.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON + * + * This file is part of Kiss4web. + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Kiss4web. If not, see + */ +package fr.devinsy.kiss4web.dispatcher.hooks; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class ApplicationInitFailedServlet. + */ +public class ApplicationInitFailedServlet extends DirectServlet +{ + private static final long serialVersionUID = 3354542049753884236L; + private static final Logger logger = LoggerFactory.getLogger(ApplicationInitFailedServlet.class); + + /** + * Instantiates a new application init failed servlet. + */ + public ApplicationInitFailedServlet() + { + super("/fr/devinsy/kiss4web/dispatcher/hooks/applicationInitFailed.xhtml"); + } +} diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitHook.java index 83cd17c..6f6281e 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitHook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2018-2023 Christian Pierre MOMON +/* + * Copyright (C) 2018-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,24 +18,13 @@ */ package fr.devinsy.kiss4web.dispatcher.hooks; -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jakarta.servlet.ServletConfig; -import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - /** * The Class InitHook. */ -public class ApplicationInitHook extends HookCore +public class ApplicationInitHook extends DirectHook { private static Logger logger = LoggerFactory.getLogger(ApplicationInitHook.class); @@ -44,43 +33,6 @@ public class ApplicationInitHook extends HookCore */ public ApplicationInitHook() { - super(); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean matches(final ServletContext servletContext, final HttpServletRequest request) - { - boolean result; - - result = true; - - // - return result; - } - - /** - * {@inheritDoc} - */ - @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException, ServletException - { - logger.debug("Doing catch {}.", this.getClass().getName()); - - String path = servletContext.getRealPath("/") + request.getPathInfo(); - logger.info("path=[{}]", path); - - // Get page. - URL url = Hook.class.getResource("/fr/devinsy/kiss4web/dispatcher/hooks/applicationInit.xhtml"); - String xhtml = IOUtils.toString(url, StandardCharsets.UTF_8); - - // Display page. - response.setContentType("application/xhtml+xml; charset=UTF-8"); - response.getWriter().println(xhtml); - - logger.info("Application Init page returned."); + super("/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitServlet"); } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitServlet.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitServlet.java new file mode 100644 index 0000000..b672ff3 --- /dev/null +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/ApplicationInitServlet.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON + * + * This file is part of Kiss4web. + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Kiss4web. If not, see + */ +package fr.devinsy.kiss4web.dispatcher.hooks; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class ApplicationInitServlet. + */ +public class ApplicationInitServlet extends DirectServlet +{ + private static final long serialVersionUID = 6515114898805106148L; + private static final Logger logger = LoggerFactory.getLogger(ApplicationInitServlet.class); + + /** + * Instantiates a new application init servlet. + */ + public ApplicationInitServlet() + { + super("/fr/devinsy/kiss4web/dispatcher/hooks/applicationInitServlet.xhtml"); + } +} diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/BlankHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/BlankHook.java index ea15a63..1585669 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/BlankHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/BlankHook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2023 Christian Pierre MOMON +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,16 +18,12 @@ */ package fr.devinsy.kiss4web.dispatcher.hooks; -import java.io.IOException; -import java.io.PrintWriter; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletContext; import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; /** * The Class BlankHook. @@ -44,6 +40,20 @@ public class BlankHook extends HookCore super(); } + /** + * {@inheritDoc} + */ + @Override + public String getServletClassName(final ServletConfig config, final HttpServletRequest request) + { + String result; + + result = "/fr/devinsy/kiss4web/dispatcher/hooks/BlankServlet"; + + // + return result; + } + /** * {@inheritDoc} */ @@ -66,23 +76,4 @@ public class BlankHook extends HookCore // return result; } - - /** - * {@inheritDoc} - */ - @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException - { - logger.debug("Doing catch."); - - response.setContentType("text/html"); - PrintWriter out = response.getWriter(); - - out.println(""); - out.println("Null path."); - out.println(""); - - out.close(); - } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/BlankSerlvet.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/BlankSerlvet.java new file mode 100644 index 0000000..20740cd --- /dev/null +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/BlankSerlvet.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON + * + * This file is part of Kiss4web. + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Kiss4web. If not, see + */ +package fr.devinsy.kiss4web.dispatcher.hooks; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class BlankSerlvet. + */ +public class BlankSerlvet extends DirectServlet +{ + private static final long serialVersionUID = -3751754076316971589L; + private static final Logger logger = LoggerFactory.getLogger(BlankSerlvet.class); + + /** + * Instantiates a new blank serlvet. + */ + public BlankSerlvet() + { + super("/fr/devinsy/kiss4web/dispatcher/hooks/blank.xhtml"); + } +} diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/StatisticsHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/DirectHook.java similarity index 62% rename from src/fr/devinsy/kiss4web/dispatcher/hooks/StatisticsHook.java rename to src/fr/devinsy/kiss4web/dispatcher/hooks/DirectHook.java index 3b6e62e..275a710 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/StatisticsHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/DirectHook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2023 Christian Pierre MOMON +/* + * Copyright (C) 2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,31 +18,48 @@ */ package fr.devinsy.kiss4web.dispatcher.hooks; -import java.io.IOException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletContext; import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; /** - * The Class StatisticsHook. + * The Class DirectHook. */ -public class StatisticsHook extends HookCore +public class DirectHook extends HookCore { - private static Logger logger = LoggerFactory.getLogger(StatisticsHook.class); + private static Logger logger = LoggerFactory.getLogger(DirectHook.class); + + private String targetClassName; /** - * Instantiates a new statistics hook. + * Instantiates a new direct hook. + * + * @param regex + * the regex + * @param targetClassName + * the target class path */ - public StatisticsHook() + public DirectHook(final String targetClassName) { super(); + this.targetClassName = targetClassName; + } - setTerminal(false); + /** + * {@inheritDoc} + */ + @Override + public String getServletClassName(final ServletConfig config, final HttpServletRequest request) + { + String result; + + result = this.targetClassName; + + // + return result; } /** @@ -58,16 +75,4 @@ public class StatisticsHook extends HookCore // return result; } - - /** - * {@inheritDoc} - */ - @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException - { - logger.debug("Doing catch."); - - // TODO store statistics. - } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/DirectServlet.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/DirectServlet.java new file mode 100644 index 0000000..f0b52c5 --- /dev/null +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/DirectServlet.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2024 Christian Pierre MOMON + * + * This file is part of Kiss4web. + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Kiss4web. If not, see + */ +package fr.devinsy.kiss4web.dispatcher.hooks; + +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; + +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * The Class StaticPageServlet. + */ +public class DirectServlet extends HttpServlet +{ + private static final long serialVersionUID = 3433035754728880755L; + private static final Logger logger = LoggerFactory.getLogger(DirectServlet.class); + + private String path; + + /** + * Instantiates a new static page servlet. + */ + public DirectServlet(final String path) + { + super(); + this.path = path; + } + + /** + * Dispatch. + * + * @param request + * the request + * @param response + * the response + * @throws IOException + * Signals that an I/O exception has occurred. + * @throws ServletException + * the servlet exception + */ + public void dispatch(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + { + // Get page. + URL url = Hook.class.getResource(this.path); + String xhtml = IOUtils.toString(url, StandardCharsets.UTF_8); + + // Display page. + response.setContentType("application/xhtml+xml; charset=UTF-8"); + response.getWriter().println(xhtml); + } + + /** + * {@inheritDoc} + */ + @Override + public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + { + dispatch(request, response); + } + + /** + * {@inheritDoc} + */ + @Override + public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + { + dispatch(request, response); + } +} diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/ErrorHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/ErrorHook.java index 78f94b5..030c7f2 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/ErrorHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/ErrorHook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2018-2023 Christian Pierre MOMON +/* + * Copyright (C) 2018-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,25 +18,13 @@ */ package fr.devinsy.kiss4web.dispatcher.hooks; -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jakarta.servlet.ServletConfig; -import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - /** * The Class ErrorHook. */ -public class ErrorHook extends HookCore +public class ErrorHook extends RewriteHook { private static Logger logger = LoggerFactory.getLogger(ErrorHook.class); @@ -45,50 +33,6 @@ public class ErrorHook extends HookCore */ public ErrorHook() { - super(); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean matches(final ServletContext servletContext, final HttpServletRequest request) - { - boolean result; - - if (new File(servletContext.getRealPath("/") + request.getPathInfo()).exists()) - { - result = true; - } - else - { - result = false; - } - - // - return result; - } - - /** - * {@inheritDoc} - */ - @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException, ServletException - { - logger.debug("Doing catch."); - - String path = servletContext.getRealPath("/") + request.getPathInfo(); - logger.info("path=[{}]", path); - - // Get page. - URL url = Hook.class.getResource("/fr/devinsy/kiss4web/dispatcher/hooks/error.xhtml"); - String xhtml = IOUtils.toString(url, StandardCharsets.UTF_8); - - // Display page. - response.setContentType("application/xhtml+xml; charset=UTF-8"); - response.getWriter().println(xhtml); - - logger.info("Error page returned for [{}].", path); + super(".*", "/fr/devinsy/kiss4web/dispatcher/hooks/ErrorServlet"); } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/ErrorServlet.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/ErrorServlet.java new file mode 100644 index 0000000..24df0e5 --- /dev/null +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/ErrorServlet.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2024 Christian Pierre MOMON + * + * This file is part of Kiss4web. + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Kiss4web. If not, see + */ +package fr.devinsy.kiss4web.dispatcher.hooks; + +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; + +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * The Class ErrorServlet. + */ +public class ErrorServlet extends HttpServlet +{ + private static final long serialVersionUID = -4906221802965761187L; + + private static final Logger logger = LoggerFactory.getLogger(ErrorServlet.class); + + private String message; + private Exception exception; + + /** + * Instantiates a new error servlet. + */ + public ErrorServlet(final String message) + { + this(message, null); + } + + /** + * Instantiates a new error servlet. + */ + public ErrorServlet(final String message, final Exception exception) + { + this.message = message; + this.exception = exception; + } + + /** + * Dispatch. + * + * @param request + * the request + * @param response + * the response + * @throws IOException + * Signals that an I/O exception has occurred. + * @throws ServletException + * the servlet exception + */ + public void dispatch(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + { + ServletContext context = this.getServletContext(); + + // Get page. + + // TODO dynamize!!! + + URL url = Hook.class.getResource("/fr/devinsy/kiss4web/dispatcher/hooks/error.xhtml"); + String xhtml = IOUtils.toString(url, StandardCharsets.UTF_8); + + // Display page. + response.setContentType("application/xhtml+xml; charset=UTF-8"); + response.getWriter().println(xhtml); + } + + /** + * {@inheritDoc} + */ + @Override + public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + { + dispatch(request, response); + } + + /** + * {@inheritDoc} + */ + @Override + public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + { + dispatch(request, response); + } +} diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/FatalHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/FatalHook.java index bc963f4..543b722 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/FatalHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/FatalHook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2018-2023 Christian Pierre MOMON +/* + * Copyright (C) 2018-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,25 +18,13 @@ */ package fr.devinsy.kiss4web.dispatcher.hooks; -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jakarta.servlet.ServletConfig; -import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - /** * The Class FatalHook. */ -public class FatalHook extends HookCore +public class FatalHook extends DirectHook { private static Logger logger = LoggerFactory.getLogger(FatalHook.class); @@ -45,50 +33,6 @@ public class FatalHook extends HookCore */ public FatalHook() { - super(); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean matches(final ServletContext servletContext, final HttpServletRequest request) - { - boolean result; - - if (new File(servletContext.getRealPath("/") + request.getPathInfo()).exists()) - { - result = true; - } - else - { - result = false; - } - - // - return result; - } - - /** - * {@inheritDoc} - */ - @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException, ServletException - { - logger.debug("Doing catch."); - - String path = servletContext.getRealPath("/") + request.getPathInfo(); - logger.info("path=[{}]", path); - - // Get page. - URL url = Hook.class.getResource("/fr/devinsy/kiss4web/dispatcher/hooks/fatal.xhtml"); - String xhtml = IOUtils.toString(url, StandardCharsets.UTF_8); - - // Display page. - response.setContentType("application/xhtml+xml; charset=UTF-8"); - response.getWriter().println(xhtml); - - logger.info("Fatal page returned."); + super("/fr/devinsy/kiss4web/dispatcher/hooks/FatalServlet"); } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/FatalServlet.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/FatalServlet.java new file mode 100644 index 0000000..c27d05d --- /dev/null +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/FatalServlet.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Christian Pierre MOMON + * + * This file is part of Kiss4web. + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Kiss4web. If not, see + */ +package fr.devinsy.kiss4web.dispatcher.hooks; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class FatalServlet. + */ +public class FatalServlet extends DirectServlet +{ + private static final long serialVersionUID = 634762859496474527L; + private static final Logger logger = LoggerFactory.getLogger(FatalServlet.class); + + /** + * Instantiates a new fatal servlet. + */ + public FatalServlet() + { + super("/fr/devinsy/kiss4web/dispatcher/hooks/fatal.xhtml"); + } +} diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/FolderHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/FolderHook.java index ba1aab9..92f1803 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/FolderHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/FolderHook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2023 Christian Pierre MOMON +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,17 +18,13 @@ */ package fr.devinsy.kiss4web.dispatcher.hooks; -import java.io.IOException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import fr.devinsy.kiss4web.dispatcher.KissDispatcherFactory; +import fr.devinsy.kiss4web.dispatcher.KissDispatcherUtils; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; /** * The Class FolderHook. @@ -45,6 +41,20 @@ public class FolderHook extends HookCore super(); } + /** + * {@inheritDoc} + */ + @Override + public String getServletClassName(final ServletConfig config, final HttpServletRequest request) + { + String result; + + result = "website." + KissDispatcherUtils.translateToClassName(request.getPathInfo()); + + // + return result; + } + /** * {@inheritDoc} */ @@ -67,17 +77,4 @@ public class FolderHook extends HookCore // return result; } - - /** - * {@inheritDoc} - */ - @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException, ServletException - { - logger.debug("Doing catch."); - - String urlPath = request.getPathInfo(); - KissDispatcherFactory.instance().dispatchPathToServlet(servletConfig, request, response, urlPath); - } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/Hook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/Hook.java index 07213b1..e493ea7 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/Hook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/Hook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2021 Christian Pierre MOMON +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,13 +18,9 @@ */ package fr.devinsy.kiss4web.dispatcher.hooks; -import java.io.IOException; - import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; /** * The Interface Hook. @@ -32,11 +28,15 @@ import jakarta.servlet.http.HttpServletResponse; public interface Hook { /** - * Checks if is terminal. + * Gets the servlet. * - * @return true if it is a final hook, false otherwise. + * @param config + * the config + * @param request + * the request + * @return the servlet */ - boolean isTerminal(); + String getServletClassName(ServletConfig config, HttpServletRequest request); /** * Matches. @@ -48,23 +48,4 @@ public interface Hook * @return true, if successful */ boolean matches(final ServletContext servletContext, final HttpServletRequest request); - - /** - * Process. - * - * @param servletConfig - * the servlet config - * @param servletContext - * the servlet context - * @param request - * the request - * @param response - * the response - * @throws IOException - * Signals that an I/O exception has occurred. - * @throws ServletException - * the servlet exception - */ - void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException, ServletException; } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/HookCore.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/HookCore.java index 021468e..370d18e 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/HookCore.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/HookCore.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2021 Christian Pierre MOMON +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -31,27 +31,5 @@ public abstract class HookCore implements Hook public HookCore() { super(); - - this.terminal = true; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isTerminal() - { - return this.terminal; - } - - /** - * Sets the terminal. - * - * @param terminal - * the new terminal - */ - public void setTerminal(final boolean terminal) - { - this.terminal = terminal; } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/HookRegister.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/HookRegister.java index fe75eee..47d92ac 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/HookRegister.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/HookRegister.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2023 Christian Pierre MOMON +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/InitFailedHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/InitFailedHook.java index 199bf73..4aece6e 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/InitFailedHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/InitFailedHook.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2023 Christian Pierre MOMON + * Copyright (C) 2018-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,77 +18,21 @@ */ package fr.devinsy.kiss4web.dispatcher.hooks; -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jakarta.servlet.ServletConfig; -import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - /** * The Class InitFailedHook. */ -public class InitFailedHook extends HookCore +public class InitFailedHook extends DirectHook { private static Logger logger = LoggerFactory.getLogger(InitFailedHook.class); /** - * Instantiates a new inits the failed hook. + * Instantiates a new init failed hook. */ public InitFailedHook() { - super(); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean matches(final ServletContext servletContext, final HttpServletRequest request) - { - boolean result; - - if (new File(servletContext.getRealPath("/") + request.getPathInfo()).exists()) - { - result = true; - } - else - { - result = false; - } - - // - return result; - } - - /** - * {@inheritDoc} - */ - @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException, ServletException - { - logger.debug("Doing catch."); - - String path = servletContext.getRealPath("/") + request.getPathInfo(); - logger.info("path=[{}]", path); - - // Get page. - URL url = Hook.class.getResource("/fr/devinsy/kiss4web/dispatcher/hooks/initFailed.xhtml"); - String xhtml = IOUtils.toString(url, StandardCharsets.UTF_8); - - // Display page. - response.setContentType("application/xhtml+xml; charset=UTF-8"); - response.getWriter().println(xhtml); - - logger.info("Init Failed page returned."); + super("/fr/devinsy/kiss4web/dispatcher/hooks/initFailedServlet.xhtml"); } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/InitFailedServlet.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/InitFailedServlet.java new file mode 100644 index 0000000..39641b7 --- /dev/null +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/InitFailedServlet.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Christian Pierre MOMON + * + * This file is part of Kiss4web. + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Kiss4web. If not, see + */ +package fr.devinsy.kiss4web.dispatcher.hooks; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class InitFailedServlet. + */ +public class InitFailedServlet extends DirectServlet +{ + private static final long serialVersionUID = -8117673535638021417L; + private static final Logger logger = LoggerFactory.getLogger(InitFailedServlet.class); + + /** + * Instantiates a new inits the failed servlet. + */ + public InitFailedServlet() + { + super("/fr/devinsy/kiss4web/dispatcher/hooks/maintenance.xhtml"); + } +} diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/InitHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/InitHook.java index 14df916..72b3945 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/InitHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/InitHook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2018-2023 Christian Pierre MOMON +/* + * Copyright (C) 2018-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,69 +18,21 @@ */ package fr.devinsy.kiss4web.dispatcher.hooks; -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jakarta.servlet.ServletConfig; -import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - /** * The Class InitHook. */ -public class InitHook extends HookCore +public class InitHook extends DirectHook { private static Logger logger = LoggerFactory.getLogger(InitHook.class); /** - * Instantiates a new inits the hook. + * Instantiates a new init the hook. */ public InitHook() { - super(); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean matches(final ServletContext servletContext, final HttpServletRequest request) - { - boolean result; - - result = true; - - // - return result; - } - - /** - * {@inheritDoc} - */ - @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException, ServletException - { - logger.debug("Doing catch {}.", this.getClass().getName()); - - String path = servletContext.getRealPath("/") + request.getPathInfo(); - logger.info("path=[{}]", path); - - // Get page. - URL url = Hook.class.getResource("/fr/devinsy/kiss4web/dispatcher/hooks/init.xhtml"); - String xhtml = IOUtils.toString(url, StandardCharsets.UTF_8); - - // Display page. - response.setContentType("application/xhtml+xml; charset=UTF-8"); - response.getWriter().println(xhtml); - - logger.info("Init page returned."); + super("/fr/devinsy/kiss4web/dispatcher/hooks/InitServlet"); } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/InitServlet.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/InitServlet.java new file mode 100644 index 0000000..0d46e97 --- /dev/null +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/InitServlet.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Christian Pierre MOMON + * + * This file is part of Kiss4web. + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Kiss4web. If not, see + */ +package fr.devinsy.kiss4web.dispatcher.hooks; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class InitServlet. + */ +public class InitServlet extends DirectServlet +{ + private static final long serialVersionUID = -6057469263221296444L; + private static final Logger logger = LoggerFactory.getLogger(InitServlet.class); + + /** + * Instantiates a new inits the servlet. + */ + public InitServlet() + { + super("/fr/devinsy/kiss4web/dispatcher/hooks/maintenance.xhtml"); + } +} diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/LongURLHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/LongURLHook.java index 8ea2b4f..54e2fed 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/LongURLHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/LongURLHook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2023 Christian Pierre MOMON +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,17 +18,13 @@ */ package fr.devinsy.kiss4web.dispatcher.hooks; -import java.io.IOException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import fr.devinsy.kiss4web.dispatcher.KissDispatcherFactory; +import fr.devinsy.kiss4web.dispatcher.KissDispatcherUtils; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; /** * The Class LongURLHook. @@ -49,13 +45,12 @@ public class LongURLHook extends HookCore * {@inheritDoc} */ @Override - public boolean matches(final ServletContext servletContext, final HttpServletRequest request) + public String getServletClassName(final ServletConfig config, final HttpServletRequest request) { - boolean result; + String result; String urlPath = request.getPathInfo(); - - result = LongURLRewriter.matches(urlPath); + result = "website." + KissDispatcherUtils.translateToClassName(LongURLRewriter.unrewrite(urlPath)); // return result; @@ -65,15 +60,23 @@ public class LongURLHook extends HookCore * {@inheritDoc} */ @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException, ServletException + public boolean matches(final ServletContext servletContext, final HttpServletRequest request) { - logger.debug("Doing catch."); + boolean result; String urlPath = request.getPathInfo(); - String rewritedURLPath = LongURLRewriter.unrewrite(urlPath); + if (LongURLRewriter.matches(urlPath)) + { + urlPath = ShortURLRewriter.unrewrite(urlPath); + result = KissDispatcherUtils.isAvailablePath(urlPath); + } + else + { + result = false; + } - KissDispatcherFactory.instance().dispatchPathToServlet(servletConfig, request, response, rewritedURLPath); + // + return result; } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/MaintenanceHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/MaintenanceHook.java index 04021bf..d81a433 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/MaintenanceHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/MaintenanceHook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2018-2023 Christian Pierre MOMON +/* + * Copyright (C) 2018-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -19,19 +19,13 @@ package fr.devinsy.kiss4web.dispatcher.hooks; import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; /** * The Class MaintenanceHook. @@ -48,6 +42,20 @@ public class MaintenanceHook extends HookCore super(); } + /** + * {@inheritDoc} + */ + @Override + public String getServletClassName(final ServletConfig config, final HttpServletRequest request) + { + String result; + + result = "/fr/devinsy/kiss4web/dispatcher/hooks/MaintenanceServlet"; + + // + return result; + } + /** * {@inheritDoc} */ @@ -68,27 +76,4 @@ public class MaintenanceHook extends HookCore // return result; } - - /** - * {@inheritDoc} - */ - @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException, ServletException - { - logger.debug("Doing catch {}.", this.getClass().getName()); - - String path = servletContext.getRealPath("/") + request.getPathInfo(); - logger.info("path=[{}]", path); - - // Get page. - URL url = Hook.class.getResource("/fr/devinsy/kiss4web/dispatcher/hooks/maintenance.xhtml"); - String xhtml = IOUtils.toString(url, StandardCharsets.UTF_8); - - // Display page. - response.setContentType("application/xhtml+xml; charset=UTF-8"); - response.getWriter().println(xhtml); - - logger.info("Maintenance page returned."); - } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/MaintenanceServlet.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/MaintenanceServlet.java new file mode 100644 index 0000000..c2428d1 --- /dev/null +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/MaintenanceServlet.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Christian Pierre MOMON + * + * This file is part of Kiss4web. + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Kiss4web. If not, see + */ +package fr.devinsy.kiss4web.dispatcher.hooks; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class MaintenanceServlet. + */ +public class MaintenanceServlet extends DirectServlet +{ + private static final long serialVersionUID = 1116048013331691997L; + private static final Logger logger = LoggerFactory.getLogger(MaintenanceServlet.class); + + /** + * Instantiates a new maintenance servlet. + */ + public MaintenanceServlet() + { + super("/fr/devinsy/kiss4web/dispatcher/hooks/maintenance.xhtml"); + } +} diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/RewriteHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/RewriteHook.java index f8dbc96..bf0274a 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/RewriteHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/RewriteHook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2024 Christian Pierre MOMON +/* + * Copyright (C) 2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,18 +18,15 @@ */ package fr.devinsy.kiss4web.dispatcher.hooks; -import java.io.IOException; import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import fr.devinsy.kiss4web.dispatcher.KissDispatcherFactory; +import fr.devinsy.kiss4web.dispatcher.KissDispatcherUtils; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; /** * The Class RewriteHook. @@ -39,16 +36,41 @@ public class RewriteHook extends HookCore private static Logger logger = LoggerFactory.getLogger(RewriteHook.class); private Pattern pattern; - private String targetClassPath; + private String targetClassName; /** - * Instantiates a new XHTML hook. + * Instantiates a new rewrite hook. + * + * @param regex + * the regex + * @param targetClassName + * the target class name */ - public RewriteHook(final String regex, final String targetClassPath) + public RewriteHook(final String regex, final String targetClassName) { super(); this.pattern = Pattern.compile(regex); - this.targetClassPath = targetClassPath; + this.targetClassName = targetClassName; + } + + /** + * Gets the servlet class path. + * + * @param config + * the config + * @param request + * the request + * @return the servlet class path + */ + @Override + public String getServletClassName(final ServletConfig config, final HttpServletRequest request) + { + String result; + + result = this.targetClassName; + + // + return result; } /** @@ -61,9 +83,9 @@ public class RewriteHook extends HookCore String urlPath = request.getPathInfo(); - if ((this.pattern.matcher(urlPath).matches()) && (!KissDispatcherFactory.instance().isAvailablePath(urlPath))) + if (this.pattern.matcher(urlPath).matches()) { - result = true; + result = KissDispatcherUtils.isAvailablePath(this.targetClassName); } else { @@ -73,16 +95,4 @@ public class RewriteHook extends HookCore // return result; } - - /** - * {@inheritDoc} - */ - @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException, ServletException - { - logger.debug("Doing catch."); - - KissDispatcherFactory.instance().dispatchPathToServlet(servletConfig, request, response, this.targetClassPath); - } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/RootHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/RootHook.java index d0bab3f..6dd3d00 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/RootHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/RootHook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2021 Christian Pierre MOMON +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,17 +18,13 @@ */ package fr.devinsy.kiss4web.dispatcher.hooks; -import java.io.IOException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import fr.devinsy.kiss4web.dispatcher.KissDispatcherFactory; +import fr.devinsy.kiss4web.dispatcher.KissDispatcherUtils; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; /** * The Class RootHook. @@ -45,6 +41,26 @@ public class RootHook extends HookCore super(); } + /** + * Gets the servlet class path. + * + * @param config + * the config + * @param request + * the request + * @return the servlet class path + */ + @Override + public String getServletClassName(final ServletConfig config, final HttpServletRequest request) + { + String result; + + result = "website." + KissDispatcherUtils.translateToClassName("/index.xhtml"); + + // + return result; + } + /** * {@inheritDoc} */ @@ -67,18 +83,4 @@ public class RootHook extends HookCore // return result; } - - /** - * {@inheritDoc} - */ - @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException, ServletException - { - logger.debug("Doing catch."); - - String classPath = "index.xhtml"; - - KissDispatcherFactory.instance().dispatchPathToServlet(servletConfig, request, response, classPath); - } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/ShortURLHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/ShortURLHook.java index 1967f72..b6f89bc 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/ShortURLHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/ShortURLHook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2021 Christian Pierre MOMON +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,17 +18,13 @@ */ package fr.devinsy.kiss4web.dispatcher.hooks; -import java.io.IOException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import fr.devinsy.kiss4web.dispatcher.KissDispatcherFactory; +import fr.devinsy.kiss4web.dispatcher.KissDispatcherUtils; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; /** * The Class ShortURLHook. @@ -49,20 +45,16 @@ public class ShortURLHook extends HookCore * {@inheritDoc} */ @Override - public boolean matches(final ServletContext servletContext, final HttpServletRequest request) + public String getServletClassName(final ServletConfig config, final HttpServletRequest request) { - boolean result; + String result; + + logger.debug("Doing catch."); String urlPath = request.getPathInfo(); + result = "website." + KissDispatcherUtils.translateToClassName(ShortURLRewriter.unrewrite(urlPath)); - if ((ShortURLRewriter.matches(urlPath)) && (!KissDispatcherFactory.instance().isAvailablePath(urlPath))) - { - result = true; - } - else - { - result = false; - } + logger.info("rewritedURLPath={}", result); // return result; @@ -72,16 +64,23 @@ public class ShortURLHook extends HookCore * {@inheritDoc} */ @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException, ServletException + public boolean matches(final ServletContext servletContext, final HttpServletRequest request) { - logger.debug("Doing catch."); + boolean result; String urlPath = request.getPathInfo(); - String rewritedURLPath = ShortURLRewriter.unrewrite(urlPath); - logger.info("rewritedURLPath={}", rewritedURLPath); + if (ShortURLRewriter.matches(urlPath)) + { + urlPath = ShortURLRewriter.unrewrite(urlPath); + result = KissDispatcherUtils.isAvailablePath(urlPath); + } + else + { + result = false; + } - KissDispatcherFactory.instance().dispatchPathToServlet(servletConfig, request, response, rewritedURLPath); + // + return result; } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/WebContentHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/WebContentHook.java index ca1f894..7818b3d 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/WebContentHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/WebContentHook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2023 Christian Pierre MOMON +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -19,17 +19,14 @@ package fr.devinsy.kiss4web.dispatcher.hooks; import java.io.File; -import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import fr.devinsy.kiss4web.dispatcher.KissDispatcherUtils; +import fr.devinsy.kiss4web.Kiss4webException; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; /** * The Class WebContentHook. @@ -46,6 +43,22 @@ public class WebContentHook extends HookCore super(); } + /** + * {@inheritDoc} + * + * @throws Kiss4webException + */ + @Override + public String getServletClassName(final ServletConfig servletConfig, final HttpServletRequest request) + { + String result; + + result = WebContentServlet.class.getCanonicalName(); + + // + return result; + } + /** * {@inheritDoc} */ @@ -67,22 +80,4 @@ public class WebContentHook extends HookCore // return result; } - - /** - * {@inheritDoc} - */ - @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException, ServletException - { - logger.debug("Doing catch."); - - String path = servletContext.getRealPath("/") + request.getPathInfo(); - logger.info("path=[{}]", path); - - String mimeType = servletContext.getMimeType(path); - KissDispatcherUtils.returnInlineFile(response, new File(path), mimeType); - - logger.info("File returned directly [{}] with mimetype [{}].", path, servletContext.getMimeType(path)); - } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/WebContentServlet.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/WebContentServlet.java new file mode 100755 index 0000000..56dfbe0 --- /dev/null +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/WebContentServlet.java @@ -0,0 +1,91 @@ +/** + * Copyright (C) 2006-2024 Christian Pierre MOMON + * + * This file is part of Kiss4web. + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Kiss4web. If not, see + */ +package fr.devinsy.kiss4web.dispatcher.hooks; + +import java.io.File; +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fr.devinsy.kiss4web.dispatcher.KissDispatcherUtils; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * The Class WebContentServlet. + */ +public class WebContentServlet extends HttpServlet +{ + private static final long serialVersionUID = 3203080393289058696L; + private static final Logger logger = LoggerFactory.getLogger(WebContentServlet.class); + + /** + * Instantiates a new web content servlet. + */ + public WebContentServlet() + { + } + + /** + * Dispatch. + * + * @param request + * the request + * @param response + * the response + * @throws IOException + * Signals that an I/O exception has occurred. + * @throws ServletException + * the servlet exception + */ + public void dispatch(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + { + ServletContext context = this.getServletContext(); + + String path = context.getRealPath("/") + request.getPathInfo(); + logger.info("path=[{}]", path); + + String mimeType = context.getMimeType(path); + KissDispatcherUtils.returnInlineFile(response, new File(path), mimeType); + + logger.info("File returned directly [{}] with mimetype [{}].", path, mimeType); + } + + /** + * {@inheritDoc} + */ + @Override + public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + { + dispatch(request, response); + } + + /** + * {@inheritDoc} + */ + @Override + public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + { + dispatch(request, response); + } +} diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/WebInfHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/WebInfHook.java index fa4ce84..7ea27a2 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/WebInfHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/WebInfHook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2023 Christian Pierre MOMON +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -19,17 +19,13 @@ package fr.devinsy.kiss4web.dispatcher.hooks; import java.io.File; -import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import fr.devinsy.kiss4web.dispatcher.KissDispatcherUtils; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; /** * The Class WebInfHook. @@ -46,6 +42,19 @@ public class WebInfHook extends HookCore super(); } + /** + * {@inheritDoc} + */ + @Override + public String getServletClassName(final ServletConfig servletConfig, final HttpServletRequest request) + { + String result; + + result = WebInfServlet.class.getCanonicalName(); + // + return result; + } + /** * {@inheritDoc} */ @@ -68,22 +77,4 @@ public class WebInfHook extends HookCore return result; } - /** - * {@inheritDoc} - */ - @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException, ServletException - { - logger.debug("Doing catch."); - - String path = servletContext.getRealPath("/") + "WEB-INF/classes/website" + request.getPathInfo(); - - logger.info("path=[{}]", path); - - String mimeType = servletContext.getMimeType(path); - KissDispatcherUtils.returnInlineFile(response, new File(path), mimeType); - - logger.info("File returned directly [{}] with mimetype [{}].", path, servletContext.getMimeType(path)); - } } diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/WebInfServlet.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/WebInfServlet.java new file mode 100644 index 0000000..ff584b7 --- /dev/null +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/WebInfServlet.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON + * + * This file is part of Kiss4web. + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Kiss4web. If not, see + */ +package fr.devinsy.kiss4web.dispatcher.hooks; + +import java.io.File; +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fr.devinsy.kiss4web.dispatcher.KissDispatcherUtils; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * The Class WebInfServlet. + */ +public class WebInfServlet extends HttpServlet +{ + private static final long serialVersionUID = -6085589095239389710L; + private static final Logger logger = LoggerFactory.getLogger(WebInfServlet.class); + + /** + * Instantiates a new web inf servlet. + */ + public WebInfServlet() + { + } + + /** + * Dispatch. + * + * @param request + * the request + * @param response + * the response + * @throws IOException + * Signals that an I/O exception has occurred. + * @throws ServletException + * the servlet exception + */ + public void dispatch(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + { + ServletContext context = this.getServletContext(); + + String path = context.getRealPath("/") + "WEB-INF/classes/website" + request.getPathInfo(); + + logger.info("path=[{}]", path); + + String mimeType = context.getMimeType(path); + KissDispatcherUtils.returnInlineFile(response, new File(path), mimeType); + + logger.info("File returned directly [{}] with mimetype [{}].", path, mimeType); + } + + /** + * {@inheritDoc} + */ + @Override + public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + { + dispatch(request, response); + } + + /** + * {@inheritDoc} + */ + @Override + public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + { + dispatch(request, response); + } +} diff --git a/src/fr/devinsy/kiss4web/dispatcher/hooks/XHTMLHook.java b/src/fr/devinsy/kiss4web/dispatcher/hooks/XHTMLHook.java index fe51001..709f6a5 100644 --- a/src/fr/devinsy/kiss4web/dispatcher/hooks/XHTMLHook.java +++ b/src/fr/devinsy/kiss4web/dispatcher/hooks/XHTMLHook.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2006-2023 Christian Pierre MOMON +/* + * Copyright (C) 2006-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -18,17 +18,13 @@ */ package fr.devinsy.kiss4web.dispatcher.hooks; -import java.io.IOException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import fr.devinsy.kiss4web.dispatcher.KissDispatcherFactory; +import fr.devinsy.kiss4web.dispatcher.KissDispatcherUtils; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; /** * The Class XHTMLHook. @@ -45,6 +41,20 @@ public class XHTMLHook extends HookCore super(); } + /** + * {@inheritDoc} + */ + @Override + public String getServletClassName(final ServletConfig servletConfig, final HttpServletRequest request) + { + String result; + + result = "website." + KissDispatcherUtils.translateToClassName(request.getPathInfo()); + + // + return result; + } + /** * {@inheritDoc} */ @@ -67,18 +77,4 @@ public class XHTMLHook extends HookCore // return result; } - - /** - * {@inheritDoc} - */ - @Override - public void process(final ServletConfig servletConfig, final ServletContext servletContext, final HttpServletRequest request, - final HttpServletResponse response) throws IOException, ServletException - { - logger.debug("Doing catch."); - - String urlPath = request.getPathInfo(); - - KissDispatcherFactory.instance().dispatchPathToServlet(servletConfig, request, response, urlPath); - } } diff --git a/test/fr/devinsy/kiss4web/dispatcher/DispatcherFactoryTest.java b/test/fr/devinsy/kiss4web/dispatcher/DispatcherUtilsTest.java similarity index 78% rename from test/fr/devinsy/kiss4web/dispatcher/DispatcherFactoryTest.java rename to test/fr/devinsy/kiss4web/dispatcher/DispatcherUtilsTest.java index 0cd5d40..a2af618 100644 --- a/test/fr/devinsy/kiss4web/dispatcher/DispatcherFactoryTest.java +++ b/test/fr/devinsy/kiss4web/dispatcher/DispatcherUtilsTest.java @@ -1,5 +1,5 @@ -/** - * Copyright (C) 2021 Christian Pierre MOMON +/* + * Copyright (C) 2021-2024 Christian Pierre MOMON * * This file is part of Kiss4web. * @@ -26,9 +26,9 @@ import org.slf4j.LoggerFactory; import fr.devinsy.kiss4web.dispatcher.hooks.ShortURLHook; /** - * The Class DispatcherFactoryTest. + * The Class DispatcherUtilsTest. */ -public class DispatcherFactoryTest +public class DispatcherUtilsTest { private static Logger logger = LoggerFactory.getLogger(ShortURLHook.class); @@ -39,7 +39,7 @@ public class DispatcherFactoryTest public void testTranslateToClassName01() { String source = "/"; - String target = KissDispatcherFactory.translateToClassName(source); + String target = KissDispatcherUtils.translateToClassName(source); Assert.assertEquals("IndexXhtml", target); } @@ -50,7 +50,7 @@ public class DispatcherFactoryTest public void testTranslateToClassName02() { String source = "/foo"; - String target = KissDispatcherFactory.translateToClassName(source); + String target = KissDispatcherUtils.translateToClassName(source); Assert.assertEquals("Foo", target); } @@ -61,7 +61,7 @@ public class DispatcherFactoryTest public void testTranslateToClassName03() { String source = "/foo.xhtml"; - String target = KissDispatcherFactory.translateToClassName(source); + String target = KissDispatcherUtils.translateToClassName(source); Assert.assertEquals("FooXhtml", target); } @@ -72,7 +72,7 @@ public class DispatcherFactoryTest public void testTranslateToClassName04() { String source = "/foo/bar.xhtml"; - String target = KissDispatcherFactory.translateToClassName(source); + String target = KissDispatcherUtils.translateToClassName(source); Assert.assertEquals("foo.BarXhtml", target); } @@ -83,7 +83,7 @@ public class DispatcherFactoryTest public void testTranslateToClassName05() { String source = "/fooBarBaz/fooBarBaz.xhtml"; - String target = KissDispatcherFactory.translateToClassName(source); + String target = KissDispatcherUtils.translateToClassName(source); Assert.assertEquals("fooBarBaz.FooBarBazXhtml", target); } @@ -94,7 +94,7 @@ public class DispatcherFactoryTest public void testTranslateToClassName06() { String source = "/foo_bar-baz/foo_bar-baz.xhtml"; - String target = KissDispatcherFactory.translateToClassName(source); + String target = KissDispatcherUtils.translateToClassName(source); Assert.assertEquals("foo_bar-baz.FooBarBazXhtml", target); } }