src/main/kotlin/de/uapcore/lightpit/AbstractServlet.kt

Sat, 09 Nov 2024 11:47:20 +0100

author
Mike Becker <universe@uap-core.de>
date
Sat, 09 Nov 2024 11:47:20 +0100
changeset 335
1eed60b779da
parent 298
1275eb652008
permissions
-rw-r--r--

change language menu to settings menu and add timezone settings - fixes #402

184
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
1 /*
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
2 * Copyright 2021 Mike Becker. All rights reserved.
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
3 *
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
4 * Redistribution and use in source and binary forms, with or without
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
5 * modification, are permitted provided that the following conditions are met:
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
6 *
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
7 * 1. Redistributions of source code must retain the above copyright
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
8 * notice, this list of conditions and the following disclaimer.
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
9 *
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
10 * 2. Redistributions in binary form must reproduce the above copyright
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
11 * notice, this list of conditions and the following disclaimer in the
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
12 * documentation and/or other materials provided with the distribution.
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
13 *
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
17 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
20 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
21 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
22 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
24 */
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
25
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
26 package de.uapcore.lightpit
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
27
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
28 import de.uapcore.lightpit.DataSourceProvider.Companion.SC_ATTR_NAME
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
29 import de.uapcore.lightpit.dao.DataAccessObject
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
30 import de.uapcore.lightpit.dao.createDataAccessObject
298
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
31 import jakarta.servlet.http.Cookie
254
55ca6cafc3dd #233 migrate to Jakarta EE and update dependencies
Mike Becker <universe@uap-core.de>
parents: 247
diff changeset
32 import jakarta.servlet.http.HttpServlet
55ca6cafc3dd #233 migrate to Jakarta EE and update dependencies
Mike Becker <universe@uap-core.de>
parents: 247
diff changeset
33 import jakarta.servlet.http.HttpServletRequest
55ca6cafc3dd #233 migrate to Jakarta EE and update dependencies
Mike Becker <universe@uap-core.de>
parents: 247
diff changeset
34 import jakarta.servlet.http.HttpServletResponse
184
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
35 import java.sql.SQLException
335
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
36 import java.time.ZoneId
184
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
37 import java.util.*
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
38
247
e71ae69c68c0 remove log4j entirely
Mike Becker <universe@uap-core.de>
parents: 208
diff changeset
39 abstract class AbstractServlet : HttpServlet() {
298
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
40
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
41 companion object {
335
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
42 const val COOKIE_MAX_AGE = 2592000 // 30 days
298
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
43 const val LANGUAGE_COOKIE_NAME = "lpit_language"
335
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
44 const val TIMEZONE_COOKIE_NAME = "lpit_timezone"
298
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
45 }
247
e71ae69c68c0 remove log4j entirely
Mike Becker <universe@uap-core.de>
parents: 208
diff changeset
46
e71ae69c68c0 remove log4j entirely
Mike Becker <universe@uap-core.de>
parents: 208
diff changeset
47 protected val logger = MyLogger()
184
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
48
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
49 /**
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
50 * Contains the GET request mappings.
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
51 */
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
52 private val getMappings = mutableMapOf<PathPattern, MappingMethod>()
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
53
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
54 /**
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
55 * Contains the POST request mappings.
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
56 */
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
57 private val postMappings = mutableMapOf<PathPattern, MappingMethod>()
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
58
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
59 protected fun get(pattern: String, method: MappingMethod) {
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
60 getMappings[PathPattern(pattern)] = method
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
61 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
62
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
63 protected fun post(pattern: String, method: MappingMethod) {
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
64 postMappings[PathPattern(pattern)] = method
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
65 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
66
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
67 private fun notFound(http: HttpRequest, dao: DataAccessObject) {
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
68 http.response.sendError(HttpServletResponse.SC_NOT_FOUND)
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
69 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
70
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
71 private fun findMapping(
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
72 mappings: Map<PathPattern, MappingMethod>,
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
73 req: HttpServletRequest
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
74 ): Pair<PathPattern, MappingMethod> {
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
75 val requestPath = sanitizedRequestPath(req)
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
76 val candidates = mappings.filter { it.key.matches(requestPath) }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
77 return if (candidates.isEmpty()) {
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
78 Pair(PathPattern(requestPath), ::notFound)
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
79 } else {
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
80 if (candidates.size > 1) {
247
e71ae69c68c0 remove log4j entirely
Mike Becker <universe@uap-core.de>
parents: 208
diff changeset
81 logger.warn("Ambiguous mapping for request path '{0}'", requestPath)
184
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
82 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
83 candidates.entries.first().toPair()
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
84 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
85 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
86
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
87 private fun invokeMapping(
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
88 mapping: Pair<PathPattern, MappingMethod>,
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
89 req: HttpServletRequest,
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
90 resp: HttpServletResponse,
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
91 dao: DataAccessObject
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
92 ) {
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
93 val params = mapping.first.obtainPathParameters(sanitizedRequestPath(req))
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
94 val method = mapping.second
247
e71ae69c68c0 remove log4j entirely
Mike Becker <universe@uap-core.de>
parents: 208
diff changeset
95 logger.trace("invoke {0}", method)
184
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
96 method(HttpRequest(req, resp, params), dao)
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
97 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
98
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
99 private fun sanitizedRequestPath(req: HttpServletRequest) = req.pathInfo ?: "/"
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
100
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
101 private fun doProcess(
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
102 req: HttpServletRequest,
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
103 resp: HttpServletResponse,
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
104 mappings: Map<PathPattern, MappingMethod>
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
105 ) {
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
106 val session = req.session
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
107
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
108 // the very first thing to do is to force UTF-8
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
109 req.characterEncoding = "UTF-8"
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
110
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
111 // set some internal request attributes
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
112 val http = HttpRequest(req, resp)
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
113 val fullPath = req.servletPath + Optional.ofNullable(req.pathInfo).orElse("")
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
114 req.setAttribute(Constants.REQ_ATTR_BASE_HREF, http.baseHref)
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
115 req.setAttribute(Constants.REQ_ATTR_PATH, fullPath)
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
116 req.getHeader("Referer")?.let {
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
117 // TODO: add a sanity check to avoid link injection
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
118 req.setAttribute(Constants.REQ_ATTR_REFERER, it)
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
119 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
120
298
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
121 // choose the requested language as session language (if available)
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
122 if (session.getAttribute(Constants.SESSION_ATTR_LANGUAGE) == null) {
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
123 // language selection stored in cookie
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
124 val cookieLocale = cookieLanguage(http)
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
125
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
126 // if no cookie, fall back to request locale a.k.a "Browser Language"
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
127 val reqLocale = cookieLocale ?: req.locale
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
128
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
129 val availableLanguages = availableLanguages()
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
130 val sessionLocale = if (availableLanguages.contains(reqLocale)) reqLocale else availableLanguages.first()
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
131
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
132 // select the language (this will also refresh the cookie max-age)
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
133 selectLanguage(http, sessionLocale)
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
134
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
135 logger.debug(
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
136 "Setting language for new session {0}: {1}", session.id, sessionLocale.displayLanguage
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
137 )
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
138 } else {
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
139 val sessionLocale = session.getAttribute(Constants.SESSION_ATTR_LANGUAGE) as Locale
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
140 resp.locale = sessionLocale
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
141 logger.trace("Continuing session {0} with language {1}", session.id, sessionLocale)
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
142 }
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
143
335
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
144 // determine the timezone
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
145 if (session.getAttribute(Constants.SESSION_ATTR_TIMEZONE) == null) {
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
146 // timezone selection stored in cookie
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
147 val cookieTimezone = cookieTimezone(http)
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
148
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
149 // if no cookie, fall back to server's timezone (the browser does not transmit one)
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
150 val timezone = cookieTimezone ?: ZoneId.systemDefault()
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
151
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
152 selectTimezone(http, timezone)
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
153 logger.debug("Timezone for session {0} set to {1}", session.id, timezone)
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
154 }
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
155
184
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
156 // if this is an error path, bypass the normal flow
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
157 if (fullPath.startsWith("/error/")) {
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
158 http.styleSheets = listOf("error")
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
159 http.render("error")
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
160 return
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
161 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
162
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
163 // obtain a connection and create the data access objects
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
164 val dsp = req.servletContext.getAttribute(SC_ATTR_NAME) as DataSourceProvider
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
165 val dialect = dsp.dialect
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
166 val ds = dsp.dataSource
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
167 if (ds == null) {
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
168 resp.sendError(
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
169 HttpServletResponse.SC_SERVICE_UNAVAILABLE,
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
170 "JNDI DataSource lookup failed. See log for details."
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
171 )
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
172 return
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
173 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
174 try {
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
175 ds.connection.use { connection ->
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
176 val dao = createDataAccessObject(dialect, connection)
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
177 try {
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
178 connection.autoCommit = false
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
179 invokeMapping(findMapping(mappings, req), req, resp, dao)
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
180 connection.commit()
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
181 } catch (ex: SQLException) {
247
e71ae69c68c0 remove log4j entirely
Mike Becker <universe@uap-core.de>
parents: 208
diff changeset
182 logger.warn("Database transaction failed (Code {0}): {1}", ex.errorCode, ex.message)
e71ae69c68c0 remove log4j entirely
Mike Becker <universe@uap-core.de>
parents: 208
diff changeset
183 logger.debug("Details: ", ex)
184
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
184 resp.sendError(
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
185 HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
186 "Unhandled Transaction Error - Code: " + ex.errorCode
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
187 )
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
188 connection.rollback()
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
189 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
190 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
191 } catch (ex: SQLException) {
247
e71ae69c68c0 remove log4j entirely
Mike Becker <universe@uap-core.de>
parents: 208
diff changeset
192 logger.error("Severe Database Exception (Code {0}): {1}", ex.errorCode, ex.message)
e71ae69c68c0 remove log4j entirely
Mike Becker <universe@uap-core.de>
parents: 208
diff changeset
193 logger.debug("Details: ", ex)
184
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
194 resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Database Error - Code: " + ex.errorCode)
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
195 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
196 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
197
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
198 override fun doGet(req: HttpServletRequest, resp: HttpServletResponse) {
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
199 doProcess(req, resp, getMappings)
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
200 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
201
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
202 override fun doPost(req: HttpServletRequest, resp: HttpServletResponse) {
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
203 doProcess(req, resp, postMappings)
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
204 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
205
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
206 protected fun availableLanguages(): List<Locale> {
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
207 val langTags = servletContext.getInitParameter(Constants.CTX_ATTR_LANGUAGES)?.split(",")?.map(String::trim) ?: emptyList()
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
208 val locales = langTags.map(Locale::forLanguageTag).filter { it.language.isNotEmpty() }
208
785820da6485 fixes response locale not set for new sessions
Mike Becker <universe@uap-core.de>
parents: 184
diff changeset
209 return locales.ifEmpty { listOf(Locale.ENGLISH) }
184
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
210 }
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
211
298
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
212 private fun cookieLanguage(http: HttpRequest): Locale? =
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
213 http.request.cookies?.firstOrNull { c -> c.name == LANGUAGE_COOKIE_NAME }
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
214 ?.runCatching {Locale.forLanguageTag(this.value)}?.getOrNull()
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
215
335
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
216 protected fun sessionLanguage(http: HttpRequest) = http.session.getAttribute(Constants.SESSION_ATTR_LANGUAGE) as Locale
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
217
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
218 private fun cookieTimezone(http: HttpRequest): ZoneId? =
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
219 http.request.cookies?.firstOrNull { c -> c.name == TIMEZONE_COOKIE_NAME }
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
220 ?.runCatching { ZoneId.of(this.value)}?.getOrNull()
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
221
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
222 protected fun sessionTimezone(http: HttpRequest) = http.session.getAttribute(Constants.SESSION_ATTR_TIMEZONE) as String
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
223
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
224 protected fun selectTimezone(http: HttpRequest, zoneId: ZoneId) {
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
225 http.session.setAttribute(Constants.SESSION_ATTR_TIMEZONE, zoneId.id)
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
226 val cookie = Cookie(TIMEZONE_COOKIE_NAME, zoneId.id)
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
227 cookie.isHttpOnly = true
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
228 cookie.path = http.request.contextPath
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
229 cookie.maxAge = COOKIE_MAX_AGE
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
230 http.response.addCookie(cookie)
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
231 }
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
232
298
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
233 protected fun selectLanguage(http: HttpRequest, locale: Locale) {
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
234 http.response.locale = locale
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
235 http.session.setAttribute(Constants.SESSION_ATTR_LANGUAGE, locale)
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
236 // delete cookie if language selection matches request locale, otherwise set cookie
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
237 val cookie = Cookie(LANGUAGE_COOKIE_NAME, "")
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
238 cookie.isHttpOnly = true
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
239 cookie.path = http.request.contextPath
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
240 if (http.request.locale.language == locale.language) {
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
241 cookie.maxAge = 0
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
242 } else {
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
243 cookie.value = locale.language
335
1eed60b779da change language menu to settings menu and add timezone settings - fixes #402
Mike Becker <universe@uap-core.de>
parents: 298
diff changeset
244 cookie.maxAge = COOKIE_MAX_AGE
298
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
245 }
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
246 http.response.addCookie(cookie)
1275eb652008 add language selection cookie - fixes #352
Mike Becker <universe@uap-core.de>
parents: 254
diff changeset
247 }
184
e8eecee6aadf completes kotlin migration
Mike Becker <universe@uap-core.de>
parents:
diff changeset
248 }

mercurial