# HG changeset patch # User Mike Becker # Date 1604656232 -3600 # Node ID 4f912cd42876a5f5f0205dfa67b7e09b95f9a3b8 # Parent 1e6f16fad3a56921f4286ec8a9c93123adb18047 migrates constants and removes global functions diff -r 1e6f16fad3a5 -r 4f912cd42876 src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java --- a/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java Thu Nov 05 13:37:48 2020 +0100 +++ b/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java Fri Nov 06 10:50:32 2020 +0100 @@ -53,7 +53,7 @@ private static final Logger LOG = LoggerFactory.getLogger(AbstractLightPITServlet.class); - private static final String SITE_JSP = Functions.jspPath("site"); + private static final String SITE_JSP = jspPath("site"); @FunctionalInterface @@ -102,7 +102,7 @@ */ private DataAccessObjects createDataAccessObjects(Connection connection) throws SQLException { final var df = (DataSourceProvider) getServletContext().getAttribute(DataSourceProvider.Companion.getSC_ATTR_NAME()); - if (df.getDialect() == DatabaseDialect.Postgres) { + if (df.getDialect() == DataSourceProvider.Dialect.Postgres) { return new PGDataAccessObjects(connection); } throw new UnsupportedOperationException("Non-exhaustive if-else - this is a bug."); @@ -238,7 +238,7 @@ * @see Constants#REQ_ATTR_CONTENT_PAGE */ protected void setContentPage(HttpServletRequest req, String pageName) { - req.setAttribute(Constants.REQ_ATTR_CONTENT_PAGE, Functions.jspPath(pageName)); + req.setAttribute(Constants.REQ_ATTR_CONTENT_PAGE, jspPath(pageName)); } /** @@ -249,7 +249,7 @@ * @see Constants#REQ_ATTR_NAVIGATION */ protected void setNavigationMenu(HttpServletRequest req, String jspName) { - req.setAttribute(Constants.REQ_ATTR_NAVIGATION, Functions.jspPath(jspName)); + req.setAttribute(Constants.REQ_ATTR_NAVIGATION, jspPath(jspName)); } /** @@ -259,7 +259,7 @@ */ protected void setRedirectLocation(HttpServletRequest req, String location) { if (location.startsWith("./")) { - location = location.replaceFirst("\\./", Functions.baseHref(req)); + location = location.replaceFirst("\\./", baseHref(req)); } req.setAttribute(Constants.REQ_ATTR_REDIRECT_LOCATION, location); } @@ -277,7 +277,7 @@ * @param stylesheet the name of the stylesheet */ public void setStylesheet(HttpServletRequest req, String stylesheet) { - req.setAttribute(Constants.REQ_ATTR_STYLESHEET, Functions.enforceExt(stylesheet, ".css")); + req.setAttribute(Constants.REQ_ATTR_STYLESHEET, enforceExt(stylesheet, ".css")); } /** @@ -384,12 +384,32 @@ req.getRequestDispatcher(SITE_JSP).forward(req, resp); } + protected Optional availableLanguages() { + return Optional.ofNullable(getServletContext().getInitParameter(Constants.CTX_ATTR_LANGUAGES)).map((x) -> x.split("\\s*,\\s*")); + } + + private static String baseHref(HttpServletRequest req) { + return String.format("%s://%s:%d%s/", + req.getScheme(), + req.getServerName(), + req.getServerPort(), + req.getContextPath()); + } + + private static String enforceExt(String filename, String ext) { + return filename.endsWith(ext) ? filename : filename + ext; + } + + private static String jspPath(String filename) { + return enforceExt(Constants.JSP_PATH_PREFIX + filename, ".jsp"); + } + private void doProcess(HttpMethod method, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 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) { - Optional> availableLanguages = Functions.availableLanguages(getServletContext()).map(Arrays::asList); + Optional> availableLanguages = availableLanguages().map(Arrays::asList); 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); @@ -401,8 +421,8 @@ } // set some internal request attributes - final String fullPath = Functions.fullPath(req); - req.setAttribute(Constants.REQ_ATTR_BASE_HREF, Functions.baseHref(req)); + final String fullPath = req.getServletPath() + Optional.ofNullable(req.getPathInfo()).orElse(""); + req.setAttribute(Constants.REQ_ATTR_BASE_HREF, baseHref(req)); req.setAttribute(Constants.REQ_ATTR_PATH, fullPath); req.setAttribute(Constants.REQ_ATTR_RESOURCE_BUNDLE, getResourceBundleName()); diff -r 1e6f16fad3a5 -r 4f912cd42876 src/main/java/de/uapcore/lightpit/Constants.java --- a/src/main/java/de/uapcore/lightpit/Constants.java Thu Nov 05 13:37:48 2020 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,115 +0,0 @@ -/* - * 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: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * 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; - -import static de.uapcore.lightpit.Functions.fqn; - -/** - * Contains all non-local scope constants used by the this application. - *

- * Constants with (class) local scope are defined in their respective classes. - */ -public final class Constants { - /** - * The path where the JSP files reside. - */ - public static final String JSP_PATH_PREFIX = "/WEB-INF/jsp/"; - - /** - * The name of the generic JSP page that is displayed after a successful commit. - */ - public static final String JSP_COMMIT_SUCCESSFUL = "commit-successful"; - - /** - * Name for the context parameter specifying the available languages. - */ - public static final String CTX_ATTR_LANGUAGES = "available-languages"; - - /** - * Name for the context parameter optionally specifying a database schema. - */ - public static final String CTX_ATTR_DB_SCHEMA = "db-schema"; - - /** - * Name for the context parameter optionally specifying a database dialect. - */ - public static final String CTX_ATTR_DB_DIALECT = "db-dialect"; - - /** - * Key for the request attribute containing the resource bundle name. - */ - public static final String REQ_ATTR_RESOURCE_BUNDLE = fqn(AbstractLightPITServlet.class, "bundleName"); - - /** - * Key for the request attribute containing the optional navigation menu jsp. - */ - public static final String REQ_ATTR_NAVIGATION = fqn(AbstractLightPITServlet.class, "navMenu"); - - /** - * Key for the request attribute containing the base href. - */ - public static final String REQ_ATTR_BASE_HREF = fqn(AbstractLightPITServlet.class, "base_href"); - - /** - * Key for the request attribute containing the full path information (servlet path + path info). - */ - public static final String REQ_ATTR_PATH = fqn(AbstractLightPITServlet.class, "path"); - - /** - * Key for the name of the page which should be rendered. - */ - public static final String REQ_ATTR_CONTENT_PAGE = fqn(AbstractLightPITServlet.class, "content-page"); - - /** - * Key for the view model object (the type depends on the rendered site). - */ - public static final String REQ_ATTR_VIEWMODEL = "viewmodel"; - - /** - * Key for the name of the additional stylesheet used by a module. - */ - public static final String REQ_ATTR_STYLESHEET = fqn(AbstractLightPITServlet.class, "extraCss"); - - /** - * Key for a location the page shall redirect to. - * Will be used in a meta element. - */ - public static final String REQ_ATTR_REDIRECT_LOCATION = fqn(AbstractLightPITServlet.class, "redirectLocation"); - - /** - * Key for the current language selection within the session. - */ - public static final String SESSION_ATTR_LANGUAGE = fqn(AbstractLightPITServlet.class, "language"); - - /** - * This class is not instantiatable. - */ - private Constants() { - } -} diff -r 1e6f16fad3a5 -r 4f912cd42876 src/main/java/de/uapcore/lightpit/Functions.java --- a/src/main/java/de/uapcore/lightpit/Functions.java Thu Nov 05 13:37:48 2020 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -/* - * 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: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * 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; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import java.util.Optional; - -/** - * Contains common static functions. - */ -public final class Functions { - - private static final Logger LOG = LoggerFactory.getLogger(Functions.class); - - public static Optional availableLanguages(ServletContext ctx) { - return Optional.ofNullable(ctx.getInitParameter(Constants.CTX_ATTR_LANGUAGES)).map((x) -> x.split("\\s*,\\s*")); - } - - public static String enforceExt(String filename, String ext) { - return filename.endsWith(ext) ? filename : filename + ext; - } - - public static String jspPath(String filename) { - return enforceExt(Constants.JSP_PATH_PREFIX + filename, ".jsp"); - } - - public static String fqn(String base, String name) { - return base + "." + name; - } - - public static String fqn(Class clazz, String name) { - return fqn(clazz.getName(), name); - } - - public static String baseHref(HttpServletRequest req) { - return String.format("%s://%s:%d%s/", - req.getScheme(), - req.getServerName(), - req.getServerPort(), - req.getContextPath()); - } - - public static String fullPath(HttpServletRequest req) { - return req.getServletPath() + Optional.ofNullable(req.getPathInfo()).orElse(""); - } - - public static int parseIntOrZero(String str) { - try { - return Integer.parseInt(str); - } catch (NumberFormatException ex) { - return 0; - } - } - - /** - * This class is not instantiatable. - */ - private Functions() { - } -} diff -r 1e6f16fad3a5 -r 4f912cd42876 src/main/java/de/uapcore/lightpit/modules/LanguageModule.java --- a/src/main/java/de/uapcore/lightpit/modules/LanguageModule.java Thu Nov 05 13:37:48 2020 +0100 +++ b/src/main/java/de/uapcore/lightpit/modules/LanguageModule.java Fri Nov 06 10:50:32 2020 +0100 @@ -28,7 +28,10 @@ */ package de.uapcore.lightpit.modules; -import de.uapcore.lightpit.*; +import de.uapcore.lightpit.AbstractLightPITServlet; +import de.uapcore.lightpit.Constants; +import de.uapcore.lightpit.HttpMethod; +import de.uapcore.lightpit.RequestMapping; import de.uapcore.lightpit.viewmodel.LanguageView; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,7 +62,7 @@ public void init() throws ServletException { super.init(); - Optional langs = Functions.availableLanguages(getServletContext()); + Optional langs = availableLanguages(); if (langs.isPresent()) { for (String lang : langs.get()) { try { diff -r 1e6f16fad3a5 -r 4f912cd42876 src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java --- a/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java Thu Nov 05 13:37:48 2020 +0100 +++ b/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java Fri Nov 06 10:50:32 2020 +0100 @@ -64,6 +64,14 @@ return "localization.projects"; } + private static int parseIntOrZero(String str) { + try { + return Integer.parseInt(str); + } catch (NumberFormatException ex) { + return 0; + } + } + private void populate(ProjectView viewModel, PathParameters pathParameters, DataAccessObjects dao) throws SQLException { final var projectDao = dao.getProjectDao(); final var versionDao = dao.getVersionDao(); @@ -439,7 +447,7 @@ } final var issueDao = dao.getIssueDao(); - final var issue = issueDao.find(Functions.parseIntOrZero(pathParameters.get("issue"))); + final var issue = issueDao.find(parseIntOrZero(pathParameters.get("issue"))); if (issue == null) { resp.sendError(HttpServletResponse.SC_NOT_FOUND); return; @@ -465,7 +473,7 @@ } final var issueDao = dao.getIssueDao(); - final var issue = issueDao.find(Functions.parseIntOrZero(pathParameters.get("issue"))); + final var issue = issueDao.find(parseIntOrZero(pathParameters.get("issue"))); if (issue == null) { resp.sendError(HttpServletResponse.SC_NOT_FOUND); return; diff -r 1e6f16fad3a5 -r 4f912cd42876 src/main/kotlin/de/uapcore/lightpit/Constants.kt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/kotlin/de/uapcore/lightpit/Constants.kt Fri Nov 06 10:50:32 2020 +0100 @@ -0,0 +1,99 @@ +/* + * Copyright 2020 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 + +object Constants { + /** + * The path where the JSP files reside. + */ + const val JSP_PATH_PREFIX = "/WEB-INF/jsp/" + + /** + * The name of the generic JSP page that is displayed after a successful commit. + */ + const val JSP_COMMIT_SUCCESSFUL = "commit-successful" + + /** + * Name for the context parameter specifying the available languages. + */ + const val CTX_ATTR_LANGUAGES = "available-languages" + + /** + * Name for the context parameter optionally specifying a database schema. + */ + const val CTX_ATTR_DB_SCHEMA = "db-schema" + + /** + * Name for the context parameter optionally specifying a database dialect. + */ + const val CTX_ATTR_DB_DIALECT = "db-dialect" + + /** + * Key for the request attribute containing the resource bundle name. + */ + const val REQ_ATTR_RESOURCE_BUNDLE = "bundleName" + + /** + * Key for the request attribute containing the optional navigation menu jsp. + */ + const val REQ_ATTR_NAVIGATION = "navMenu" + + /** + * Key for the request attribute containing the base href. + */ + const val REQ_ATTR_BASE_HREF = "base_href" + + /** + * Key for the request attribute containing the full path information (servlet path + path info). + */ + const val REQ_ATTR_PATH = "requestPath" + + /** + * Key for the name of the page which should be rendered. + */ + const val REQ_ATTR_CONTENT_PAGE = "contentPage" + + /** + * Key for the view model object (the type depends on the rendered site). + */ + const val REQ_ATTR_VIEWMODEL = "viewmodel" + + /** + * Key for the name of the additional stylesheet used by a module. + */ + const val REQ_ATTR_STYLESHEET = "extraCss" + + /** + * Key for a location the page shall redirect to. + * Will be used in a meta element. + */ + const val REQ_ATTR_REDIRECT_LOCATION = "redirectLocation" + + /** + * Key for the current language selection within the session. + */ + const val SESSION_ATTR_LANGUAGE = "language" +} diff -r 1e6f16fad3a5 -r 4f912cd42876 src/main/kotlin/de/uapcore/lightpit/DataSourceProvider.kt --- a/src/main/kotlin/de/uapcore/lightpit/DataSourceProvider.kt Thu Nov 05 13:37:48 2020 +0100 +++ b/src/main/kotlin/de/uapcore/lightpit/DataSourceProvider.kt Fri Nov 06 10:50:32 2020 +0100 @@ -34,23 +34,23 @@ import javax.servlet.annotation.WebListener import javax.sql.DataSource -enum class DatabaseDialect { - Postgres -} - /** * Provides access to the database. */ @WebListener class DataSourceProvider : ServletContextListener, LoggingTrait { + enum class Dialect { + Postgres + } + /** * The database dialect to use. * May be overridden by context parameter. * * @see Constants.CTX_ATTR_DB_DIALECT */ - var dialect = DatabaseDialect.Postgres; private set + var dialect = Dialect.Postgres; private set /** * The data source, if available. @@ -130,7 +130,7 @@ val dbSchema = sc.getInitParameter(Constants.CTX_ATTR_DB_SCHEMA) ?: DB_DEFAULT_SCHEMA sc.getInitParameter(Constants.CTX_ATTR_DB_DIALECT)?.let {dbDialect -> try { - dialect = DatabaseDialect.valueOf(dbDialect) + dialect = Dialect.valueOf(dbDialect) } catch (ex: IllegalArgumentException) { logger().error( "Unknown or unsupported database dialect {}. Defaulting to {}.", diff -r 1e6f16fad3a5 -r 4f912cd42876 src/main/webapp/WEB-INF/jsp/site.jsp --- a/src/main/webapp/WEB-INF/jsp/site.jsp Thu Nov 05 13:37:48 2020 +0100 +++ b/src/main/webapp/WEB-INF/jsp/site.jsp Fri Nov 06 10:50:32 2020 +0100 @@ -1,7 +1,7 @@ <%-- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. -Copyright 2018 Mike Becker. All rights reserved. +Copyright 2020 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: