diff -r fd8c40ff78c3 -r 824d4042c857 src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java --- a/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java Sat May 09 15:19:21 2020 +0200 +++ b/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java Sat May 09 17:01:29 2020 +0200 @@ -1,8 +1,8 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * + * * Copyright 2018 Mike Becker. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -24,7 +24,7 @@ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - * + * */ package de.uapcore.lightpit; @@ -46,9 +46,9 @@ * the necessary functionality for {@link LightPITModule}s. */ public abstract class AbstractLightPITServlet extends HttpServlet { - + private static final Logger LOG = LoggerFactory.getLogger(AbstractLightPITServlet.class); - + private static final String HTML_FULL_DISPATCHER = Functions.jspPath("html_full"); /** @@ -66,14 +66,14 @@ private interface HandlerMethod { ResponseType apply(HttpServletRequest t, HttpServletResponse u) throws IOException; } - + /** * Invocation mapping gathered from the {@link RequestMapping} annotations. - * + *

* Paths in this map must always start with a leading slash, although * the specification in the annotation must not start with a leading slash. - * - * The reason for this is the different handling of empty paths in + *

+ * The reason for this is the different handling of empty paths in * {@link HttpServletRequest#getPathInfo()}. */ private final Map> mappings = new HashMap<>(); @@ -87,6 +87,11 @@ return (ModuleManager) getServletContext().getAttribute(ModuleManager.SC_ATTR_NAME); } + /** + * Returns the annotated module information. + * + * @return the module annotation + */ public final LightPITModule getModuleInfo() { return moduleInfo; } @@ -152,8 +157,8 @@ if (params.length == 2 && HttpServletRequest.class.isAssignableFrom(params[0]) && HttpServletResponse.class.isAssignableFrom(params[1])) { - - final String requestPath = "/"+mapping.get().requestPath(); + + final String requestPath = "/" + mapping.get().requestPath(); if (mappings.computeIfAbsent(mapping.get().method(), k -> new HashMap<>()). putIfAbsent(requestPath, @@ -187,73 +192,72 @@ mappings.clear(); LOG.trace("{} destroyed", getServletName()); } - + /** * Sets the name of the dynamic fragment. - * + *

* It is sufficient to specify the name without any extension. The extension * is added automatically if not specified. - * + *

* The fragment must be located in the dynamic fragments folder. - * - * @param req the servlet request object + * + * @param req the servlet request object * @param fragmentName the name of the fragment * @see Constants#DYN_FRAGMENT_PATH_PREFIX */ public void setDynamicFragment(HttpServletRequest req, String fragmentName) { req.setAttribute(Constants.REQ_ATTR_FRAGMENT, Functions.dynFragmentPath(fragmentName)); } - + /** * Specifies the name of an additional stylesheet used by the module. - * + *

* Setting an additional stylesheet is optional, but quite common for HTML * output. - * + *

* It is sufficient to specify the name without any extension. The extension * is added automatically if not specified. - * - * @param req the servlet request object + * + * @param req the servlet request object * @param stylesheet the name of the stylesheet */ public void setStylesheet(HttpServletRequest req, String stylesheet) { req.setAttribute(Constants.REQ_ATTR_STYLESHEET, Functions.enforceExt(stylesheet, ".css")); } - + private void forwardToFullView(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - + req.setAttribute(Constants.REQ_ATTR_MENU, getModuleManager().getMainMenu(getDatabaseFacade())); req.getRequestDispatcher(HTML_FULL_DISPATCHER).forward(req, resp); } - + private Optional findMapping(HttpMethod method, HttpServletRequest req) { return Optional.ofNullable(mappings.get(method)).map( (rm) -> rm.get(Optional.ofNullable(req.getPathInfo()).orElse("/")) ); } - - private void forwardAsSepcified(ResponseType type, HttpServletRequest req, HttpServletResponse resp) + + private void forwardAsSpecified(ResponseType type, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { switch (type) { - case NONE: return; + case NONE: + return; case HTML_FULL: forwardToFullView(req, resp); return; // TODO: implement remaining response types default: - // this code should be unreachable - LOG.error("ResponseType switch is not exhaustive - this is a bug!"); - throw new UnsupportedOperationException(); + throw new AssertionError("ResponseType switch is not exhaustive - this is a bug!"); } } - + private void doProcess(HttpMethod method, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // Synchronize module information with database getModuleManager().syncWithDatabase(getDatabaseFacade()); - + // choose the requested language as session language (if available) or fall back to english, otherwise HttpSession session = req.getSession(); if (session.getAttribute(Constants.SESSION_ATTR_LANGUAGE) == null) { @@ -261,28 +265,28 @@ Optional reqLocale = Optional.of(req.getLocale()); Locale sessionLocale = reqLocale.filter((rl) -> availableLanguages.map((al) -> al.contains(rl.getLanguage())).orElse(false)).orElse(Locale.ENGLISH); session.setAttribute(Constants.SESSION_ATTR_LANGUAGE, sessionLocale); - LOG.debug("Settng language for new session {}: {}", session.getId(), sessionLocale.getDisplayLanguage()); + LOG.debug("Setting language for new session {}: {}", session.getId(), sessionLocale.getDisplayLanguage()); } else { Locale sessionLocale = (Locale) session.getAttribute(Constants.SESSION_ATTR_LANGUAGE); resp.setLocale(sessionLocale); LOG.trace("Continuing session {} with language {}", session.getId(), sessionLocale); } - + // set some internal request attributes req.setAttribute(Constants.REQ_ATTR_PATH, Functions.fullPath(req)); req.setAttribute(Constants.REQ_ATTR_MODULE_CLASSNAME, this.getClass().getName()); Optional.ofNullable(moduleInfoELProxy).ifPresent((proxy) -> req.setAttribute(Constants.REQ_ATTR_MODULE_INFO, proxy)); - - + + // call the handler, if available, or send an HTTP 404 error Optional mapping = findMapping(method, req); if (mapping.isPresent()) { - forwardAsSepcified(mapping.get().apply(req, resp), req, resp); + forwardAsSpecified(mapping.get().apply(req, resp), req, resp); } else { resp.sendError(HttpServletResponse.SC_NOT_FOUND); } } - + @Override protected final void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {