--- a/src/java/de/uapcore/lightpit/AbstractLightPITServlet.java Sat Dec 23 17:28:19 2017 +0100 +++ b/src/java/de/uapcore/lightpit/AbstractLightPITServlet.java Tue Dec 26 17:36:47 2017 +0100 @@ -31,13 +31,17 @@ import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Optional; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,6 +53,8 @@ private static final Logger LOG = LoggerFactory.getLogger(AbstractLightPITServlet.class); + private static final String HTML_FULL_DISPATCHER = Functions.jspPath("html_full"); + /** * Store a reference to the annotation for quicker access. */ @@ -164,29 +170,43 @@ LOG.trace("{} destroyed", getServletName()); } - /** - * Sets several requests attributes, that can be used by the JSP. + * 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 - * @see Constants#REQ_ATTR_PATH - * @see Constants#REQ_ATTR_MODULE_CLASSNAME - * @see Constants#REQ_ATTR_MODULE_INFO + * @param fragmentName the name of the fragment + * @see Constants#DYN_FRAGMENT_PATH_PREFIX */ - private void setGenericRequestAttributes(HttpServletRequest req) { - req.setAttribute(Constants.REQ_ATTR_PATH, Functions.fullPath(req)); - - req.setAttribute(Constants.REQ_ATTR_MODULE_CLASSNAME, this.getClass().getName()); - - moduleInfoELProxy.ifPresent((proxy) -> req.setAttribute(Constants.REQ_ATTR_MODULE_INFO, proxy)); + 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 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 { - setGenericRequestAttributes(req); req.setAttribute(Constants.REQ_ATTR_MENU, getModuleManager().getMainMenu()); - req.getRequestDispatcher(Functions.jspPath("full.jsp")).forward(req, resp); + req.getRequestDispatcher(HTML_FULL_DISPATCHER).forward(req, resp); } private Optional<HandlerMethod> findMapping(HttpMethod method, HttpServletRequest req) { @@ -212,6 +232,22 @@ private void doProcess(HttpMethod method, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + HttpSession session = req.getSession(); + + // choose the requested language as session language (if available) or fall back to english, otherwise + if (session.getAttribute(Constants.SESSION_ATTR_LANGUAGE) == null) { + Optional<List<String>> availableLanguages = Functions.availableLanguages(getServletContext()).map(Arrays::asList); + Optional<Locale> 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()); + } + + req.setAttribute(Constants.REQ_ATTR_PATH, Functions.fullPath(req)); + req.setAttribute(Constants.REQ_ATTR_MODULE_CLASSNAME, this.getClass().getName()); + moduleInfoELProxy.ifPresent((proxy) -> req.setAttribute(Constants.REQ_ATTR_MODULE_INFO, proxy)); + Optional<HandlerMethod> mapping = findMapping(method, req); if (mapping.isPresent()) { forwardAsSepcified(mapping.get().apply(req, resp), req, resp);