1.1 --- a/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java Sat May 09 15:19:21 2020 +0200 1.2 +++ b/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java Sat May 09 17:01:29 2020 +0200 1.3 @@ -1,8 +1,8 @@ 1.4 /* 1.5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 1.6 - * 1.7 + * 1.8 * Copyright 2018 Mike Becker. All rights reserved. 1.9 - * 1.10 + * 1.11 * Redistribution and use in source and binary forms, with or without 1.12 * modification, are permitted provided that the following conditions are met: 1.13 * 1.14 @@ -24,7 +24,7 @@ 1.15 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.16 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 1.17 * POSSIBILITY OF SUCH DAMAGE. 1.18 - * 1.19 + * 1.20 */ 1.21 package de.uapcore.lightpit; 1.22 1.23 @@ -46,9 +46,9 @@ 1.24 * the necessary functionality for {@link LightPITModule}s. 1.25 */ 1.26 public abstract class AbstractLightPITServlet extends HttpServlet { 1.27 - 1.28 + 1.29 private static final Logger LOG = LoggerFactory.getLogger(AbstractLightPITServlet.class); 1.30 - 1.31 + 1.32 private static final String HTML_FULL_DISPATCHER = Functions.jspPath("html_full"); 1.33 1.34 /** 1.35 @@ -66,14 +66,14 @@ 1.36 private interface HandlerMethod { 1.37 ResponseType apply(HttpServletRequest t, HttpServletResponse u) throws IOException; 1.38 } 1.39 - 1.40 + 1.41 /** 1.42 * Invocation mapping gathered from the {@link RequestMapping} annotations. 1.43 - * 1.44 + * <p> 1.45 * Paths in this map must always start with a leading slash, although 1.46 * the specification in the annotation must not start with a leading slash. 1.47 - * 1.48 - * The reason for this is the different handling of empty paths in 1.49 + * <p> 1.50 + * The reason for this is the different handling of empty paths in 1.51 * {@link HttpServletRequest#getPathInfo()}. 1.52 */ 1.53 private final Map<HttpMethod, Map<String, HandlerMethod>> mappings = new HashMap<>(); 1.54 @@ -87,6 +87,11 @@ 1.55 return (ModuleManager) getServletContext().getAttribute(ModuleManager.SC_ATTR_NAME); 1.56 } 1.57 1.58 + /** 1.59 + * Returns the annotated module information. 1.60 + * 1.61 + * @return the module annotation 1.62 + */ 1.63 public final LightPITModule getModuleInfo() { 1.64 return moduleInfo; 1.65 } 1.66 @@ -152,8 +157,8 @@ 1.67 if (params.length == 2 1.68 && HttpServletRequest.class.isAssignableFrom(params[0]) 1.69 && HttpServletResponse.class.isAssignableFrom(params[1])) { 1.70 - 1.71 - final String requestPath = "/"+mapping.get().requestPath(); 1.72 + 1.73 + final String requestPath = "/" + mapping.get().requestPath(); 1.74 1.75 if (mappings.computeIfAbsent(mapping.get().method(), k -> new HashMap<>()). 1.76 putIfAbsent(requestPath, 1.77 @@ -187,73 +192,72 @@ 1.78 mappings.clear(); 1.79 LOG.trace("{} destroyed", getServletName()); 1.80 } 1.81 - 1.82 + 1.83 /** 1.84 * Sets the name of the dynamic fragment. 1.85 - * 1.86 + * <p> 1.87 * It is sufficient to specify the name without any extension. The extension 1.88 * is added automatically if not specified. 1.89 - * 1.90 + * <p> 1.91 * The fragment must be located in the dynamic fragments folder. 1.92 - * 1.93 - * @param req the servlet request object 1.94 + * 1.95 + * @param req the servlet request object 1.96 * @param fragmentName the name of the fragment 1.97 * @see Constants#DYN_FRAGMENT_PATH_PREFIX 1.98 */ 1.99 public void setDynamicFragment(HttpServletRequest req, String fragmentName) { 1.100 req.setAttribute(Constants.REQ_ATTR_FRAGMENT, Functions.dynFragmentPath(fragmentName)); 1.101 } 1.102 - 1.103 + 1.104 /** 1.105 * Specifies the name of an additional stylesheet used by the module. 1.106 - * 1.107 + * <p> 1.108 * Setting an additional stylesheet is optional, but quite common for HTML 1.109 * output. 1.110 - * 1.111 + * <p> 1.112 * It is sufficient to specify the name without any extension. The extension 1.113 * is added automatically if not specified. 1.114 - * 1.115 - * @param req the servlet request object 1.116 + * 1.117 + * @param req the servlet request object 1.118 * @param stylesheet the name of the stylesheet 1.119 */ 1.120 public void setStylesheet(HttpServletRequest req, String stylesheet) { 1.121 req.setAttribute(Constants.REQ_ATTR_STYLESHEET, Functions.enforceExt(stylesheet, ".css")); 1.122 } 1.123 - 1.124 + 1.125 private void forwardToFullView(HttpServletRequest req, HttpServletResponse resp) 1.126 throws IOException, ServletException { 1.127 - 1.128 + 1.129 req.setAttribute(Constants.REQ_ATTR_MENU, getModuleManager().getMainMenu(getDatabaseFacade())); 1.130 req.getRequestDispatcher(HTML_FULL_DISPATCHER).forward(req, resp); 1.131 } 1.132 - 1.133 + 1.134 private Optional<HandlerMethod> findMapping(HttpMethod method, HttpServletRequest req) { 1.135 return Optional.ofNullable(mappings.get(method)).map( 1.136 (rm) -> rm.get(Optional.ofNullable(req.getPathInfo()).orElse("/")) 1.137 ); 1.138 } 1.139 - 1.140 - private void forwardAsSepcified(ResponseType type, HttpServletRequest req, HttpServletResponse resp) 1.141 + 1.142 + private void forwardAsSpecified(ResponseType type, HttpServletRequest req, HttpServletResponse resp) 1.143 throws ServletException, IOException { 1.144 switch (type) { 1.145 - case NONE: return; 1.146 + case NONE: 1.147 + return; 1.148 case HTML_FULL: 1.149 forwardToFullView(req, resp); 1.150 return; 1.151 // TODO: implement remaining response types 1.152 default: 1.153 - // this code should be unreachable 1.154 - LOG.error("ResponseType switch is not exhaustive - this is a bug!"); 1.155 - throw new UnsupportedOperationException(); 1.156 + throw new AssertionError("ResponseType switch is not exhaustive - this is a bug!"); 1.157 } 1.158 } 1.159 - 1.160 + 1.161 private void doProcess(HttpMethod method, HttpServletRequest req, HttpServletResponse resp) 1.162 throws ServletException, IOException { 1.163 1.164 // Synchronize module information with database 1.165 getModuleManager().syncWithDatabase(getDatabaseFacade()); 1.166 - 1.167 + 1.168 // choose the requested language as session language (if available) or fall back to english, otherwise 1.169 HttpSession session = req.getSession(); 1.170 if (session.getAttribute(Constants.SESSION_ATTR_LANGUAGE) == null) { 1.171 @@ -261,28 +265,28 @@ 1.172 Optional<Locale> reqLocale = Optional.of(req.getLocale()); 1.173 Locale sessionLocale = reqLocale.filter((rl) -> availableLanguages.map((al) -> al.contains(rl.getLanguage())).orElse(false)).orElse(Locale.ENGLISH); 1.174 session.setAttribute(Constants.SESSION_ATTR_LANGUAGE, sessionLocale); 1.175 - LOG.debug("Settng language for new session {}: {}", session.getId(), sessionLocale.getDisplayLanguage()); 1.176 + LOG.debug("Setting language for new session {}: {}", session.getId(), sessionLocale.getDisplayLanguage()); 1.177 } else { 1.178 Locale sessionLocale = (Locale) session.getAttribute(Constants.SESSION_ATTR_LANGUAGE); 1.179 resp.setLocale(sessionLocale); 1.180 LOG.trace("Continuing session {} with language {}", session.getId(), sessionLocale); 1.181 } 1.182 - 1.183 + 1.184 // set some internal request attributes 1.185 req.setAttribute(Constants.REQ_ATTR_PATH, Functions.fullPath(req)); 1.186 req.setAttribute(Constants.REQ_ATTR_MODULE_CLASSNAME, this.getClass().getName()); 1.187 Optional.ofNullable(moduleInfoELProxy).ifPresent((proxy) -> req.setAttribute(Constants.REQ_ATTR_MODULE_INFO, proxy)); 1.188 - 1.189 - 1.190 + 1.191 + 1.192 // call the handler, if available, or send an HTTP 404 error 1.193 Optional<HandlerMethod> mapping = findMapping(method, req); 1.194 if (mapping.isPresent()) { 1.195 - forwardAsSepcified(mapping.get().apply(req, resp), req, resp); 1.196 + forwardAsSpecified(mapping.get().apply(req, resp), req, resp); 1.197 } else { 1.198 resp.sendError(HttpServletResponse.SC_NOT_FOUND); 1.199 } 1.200 } 1.201 - 1.202 + 1.203 @Override 1.204 protected final void doGet(HttpServletRequest req, HttpServletResponse resp) 1.205 throws ServletException, IOException {