You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lo...@apache.org on 2022/03/18 11:57:55 UTC
[myfaces-tobago] branch tobago-5.x updated: feat: Make selected theme storeable in session
This is an automated email from the ASF dual-hosted git repository.
lofwyr pushed a commit to branch tobago-5.x
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git
The following commit(s) were added to refs/heads/tobago-5.x by this push:
new 942f003 feat: Make selected theme storeable in session
942f003 is described below
commit 942f003c727d879c3c5095403d5483a39fe2f51e
Author: Udo Schnurpfeil <ud...@irian.eu>
AuthorDate: Fri Mar 18 12:56:28 2022 +0100
feat: Make selected theme storeable in session
issue: TOBAGO-2119
---
.../apache/myfaces/tobago/config/TobagoConfig.java | 24 ++++++++-
.../org/apache/myfaces/tobago/context/Theme.java | 6 +++
.../myfaces/tobago/context/TobagoContext.java | 58 ++++++++++++++++++----
.../internal/config/TobagoConfigFragment.java | 9 ++++
.../tobago/internal/config/TobagoConfigMerger.java | 5 ++
.../tobago/internal/config/TobagoConfigParser.java | 6 +++
.../internal/renderkit/renderer/PageRenderer.java | 7 ---
.../myfaces/tobago/internal/util/CookieUtils.java | 15 +++---
.../myfaces/tobago/config/tobago-config-5.1.xsd | 7 +++
.../config/TobagoConfigParserUnitTest.java | 16 ++++++
.../src/test/resources/tobago-config-5.1.xml | 1 +
.../src/main/webapp/WEB-INF/tobago-config.xml | 2 +
12 files changed, 128 insertions(+), 28 deletions(-)
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/config/TobagoConfig.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/config/TobagoConfig.java
index 0a74f32..7e447b3 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/config/TobagoConfig.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/config/TobagoConfig.java
@@ -56,6 +56,7 @@ public class TobagoConfig {
private String defaultThemeName;
private Map<String, ThemeImpl> availableThemes;
private boolean themeCookie;
+ private boolean themeSession;
private boolean createSessionSecret;
private boolean checkSessionSecret;
private boolean preventFrameAttacks;
@@ -106,6 +107,7 @@ public class TobagoConfig {
supportedThemes = new ArrayList<>();
availableThemes = new HashMap<>();
themeCookie = true;
+ themeSession = false;
createSessionSecret = true;
checkSessionSecret = true;
preventFrameAttacks = true;
@@ -173,6 +175,15 @@ public class TobagoConfig {
LOG.debug("searching theme: null");
return defaultTheme;
}
+ final Theme found = getThemeIfExists(name);
+ if (found != null) {
+ return found;
+ }
+ LOG.debug("searching theme '{}' not found. Using default: {}", name, defaultTheme);
+ return defaultTheme;
+ }
+
+ public Theme getThemeIfExists(final String name) {
if (defaultTheme != null && defaultTheme.getName().equals(name)) {
return defaultTheme;
}
@@ -181,8 +192,7 @@ public class TobagoConfig {
return theme;
}
}
- LOG.debug("searching theme '{}' not found. Using default: {}", name, defaultTheme);
- return defaultTheme;
+ return null;
}
public void setDefaultThemeName(final String defaultThemeName) {
@@ -229,6 +239,14 @@ public class TobagoConfig {
this.themeCookie = themeCookie;
}
+ public boolean isThemeSession() {
+ return themeSession;
+ }
+
+ public void setThemeSession(boolean themeSession) {
+ this.themeSession = themeSession;
+ }
+
public boolean isCreateSessionSecret() {
return createSessionSecret;
}
@@ -354,6 +372,8 @@ public class TobagoConfig {
builder.append(availableThemes.keySet());
builder.append(", \nthemeCookie=");
builder.append(themeCookie);
+ builder.append(", \nthemeSession=");
+ builder.append(themeSession);
builder.append(", \ncreateSessionSecret=");
builder.append(createSessionSecret);
builder.append(", \ncheckSessionSecret=");
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/context/Theme.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/context/Theme.java
index 1d66127..8b5c630 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/context/Theme.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/context/Theme.java
@@ -24,6 +24,12 @@ import org.apache.myfaces.tobago.component.Tags;
import java.util.List;
public interface Theme {
+
+ /**
+ * Internal key to manage the configured theme for the user.
+ */
+ String THEME_KEY = "tobago.theme";
+
String getName();
List<Theme> getFallbackList();
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoContext.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoContext.java
index bdcde17..f2a4ae5 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoContext.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoContext.java
@@ -30,6 +30,8 @@ import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
import java.io.Serializable;
import java.lang.invoke.MethodHandles;
import java.util.Locale;
@@ -84,29 +86,63 @@ public class TobagoContext implements Serializable {
public Theme getTheme() {
- if (theme == null) {
- final FacesContext facesContext = FacesContext.getCurrentInstance();
- final ExternalContext externalContext = facesContext.getExternalContext();
+ if (theme != null) {
+ return theme;
+ }
- final String themeName;
- final Object request = externalContext.getRequest();
- if (request instanceof HttpServletRequest && getTobagoConfig().isThemeCookie()) {
- themeName = CookieUtils.getThemeNameFromCookie((HttpServletRequest) request);
- } else {
- themeName = null;
+ final FacesContext facesContext = FacesContext.getCurrentInstance();
+ final ExternalContext externalContext = facesContext.getExternalContext();
+ final Object request = externalContext.getRequest();
+ final Object session = externalContext.getSession(false);
+
+ // load theme from session
+ if (session instanceof HttpSession && getTobagoConfig().isThemeSession()) {
+ final String themeName = (String) ((HttpSession) session).getAttribute(Theme.THEME_KEY);
+ theme = getTobagoConfig().getThemeIfExists(themeName);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("from session theme='{}'", theme.getName());
}
+ }
+
+ if (theme != null) {
+ return theme;
+ }
+ // or load it from cookie
+ if (request instanceof HttpServletRequest && getTobagoConfig().isThemeCookie()) {
+ final String themeName = CookieUtils.getThemeNameFromCookie((HttpServletRequest) request);
theme = getTobagoConfig().getTheme(themeName);
if (LOG.isDebugEnabled()) {
- LOG.debug("theme='{}'", theme.getName());
+ LOG.debug("from cookie theme='{}'", theme.getName());
}
}
- return theme;
+ if (theme != null) {
+ return theme;
+ }
+
+ // or use default
+ return getTobagoConfig().getDefaultTheme();
}
public void setTheme(final Theme theme) {
this.theme = theme;
+
+ final FacesContext facesContext = FacesContext.getCurrentInstance();
+ final ExternalContext externalContext = facesContext.getExternalContext();
+ final Object request = externalContext.getRequest();
+ final Object response = externalContext.getResponse();
+ final Object session = externalContext.getSession(false);
+
+ // save theme in cookie
+ if (response instanceof HttpServletResponse && request instanceof HttpServletRequest
+ && getTobagoConfig().isThemeCookie()) {
+ CookieUtils.setThemeNameToCookie((HttpServletRequest) request, (HttpServletResponse) response, theme.getName());
+ }
+ // save theme in session
+ if (session instanceof HttpSession && getTobagoConfig().isThemeSession()) {
+ ((HttpSession) session).setAttribute(Theme.THEME_KEY, theme.getName());
+ }
}
public UserAgent getUserAgent() {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigFragment.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigFragment.java
index e7a8f63..2990bcb 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigFragment.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigFragment.java
@@ -37,6 +37,7 @@ public class TobagoConfigFragment {
private final List<String> supportedThemeNames;
private String defaultThemeName;
private Boolean themeCookie;
+ private Boolean themeSession;
private Boolean createSessionSecret;
private Boolean checkSessionSecret;
private Boolean preventFrameAttacks;
@@ -115,6 +116,14 @@ public class TobagoConfigFragment {
this.themeCookie = Boolean.valueOf(themeCookie);
}
+ public Boolean getThemeSession() {
+ return themeSession;
+ }
+
+ public void setThemeSession(final String themeSession) {
+ this.themeSession = Boolean.valueOf(themeSession);
+ }
+
public Boolean getCreateSessionSecret() {
return createSessionSecret;
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigMerger.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigMerger.java
index c2f29b4..80a20fa 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigMerger.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigMerger.java
@@ -77,6 +77,11 @@ public class TobagoConfigMerger {
tobagoConfig.setThemeCookie(fragment.getThemeCookie());
}
+ // theme session
+ if (fragment.getThemeSession() != null) {
+ tobagoConfig.setThemeSession(fragment.getThemeSession());
+ }
+
// session secret
if (fragment.getCreateSessionSecret() != null) {
tobagoConfig.setCreateSessionSecret(fragment.getCreateSessionSecret());
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigParser.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigParser.java
index 6c711ec..dd04ec2 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigParser.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigParser.java
@@ -59,6 +59,7 @@ public class TobagoConfigParser extends TobagoConfigEntityResolver {
private static final int DEFAULT_THEME = -114431171;
private static final int SUPPORTED_THEME = -822303766;
private static final int THEME_COOKIE = 1930664680;
+ private static final int THEME_SESSION = 753861266;
private static final int CREATE_SESSION_SECRET = 413906616;
private static final int CHECK_SESSION_SECRET = 275994924;
private static final int PREVENT_FRAME_ATTACKS = 270456726;
@@ -290,6 +291,7 @@ public class TobagoConfigParser extends TobagoConfigEntityResolver {
case DEFAULT_THEME:
case SUPPORTED_THEME:
case THEME_COOKIE:
+ case THEME_SESSION:
case SUPPORTED_MARKUP:
case MARKUP:
case CREATE_SESSION_SECRET:
@@ -375,6 +377,10 @@ public class TobagoConfigParser extends TobagoConfigEntityResolver {
tobagoConfig.setThemeCookie(text);
break;
+ case THEME_SESSION:
+ tobagoConfig.setThemeSession(text);
+ break;
+
case CREATE_SESSION_SECRET:
tobagoConfig.setCreateSessionSecret(text);
break;
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
index c108680..3274cf0 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
@@ -34,7 +34,6 @@ import org.apache.myfaces.tobago.internal.component.AbstractUIPage;
import org.apache.myfaces.tobago.internal.component.AbstractUIScript;
import org.apache.myfaces.tobago.internal.component.AbstractUIStyle;
import org.apache.myfaces.tobago.internal.util.AccessKeyLogger;
-import org.apache.myfaces.tobago.internal.util.CookieUtils;
import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
import org.apache.myfaces.tobago.internal.util.ResponseUtils;
import org.apache.myfaces.tobago.internal.util.StringUtils;
@@ -61,8 +60,6 @@ import javax.faces.component.UIOutput;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
@@ -141,10 +138,6 @@ public class PageRenderer<T extends AbstractUIPage> extends RendererBase<T> {
}
final Theme theme = tobagoContext.getTheme();
- if (response instanceof HttpServletResponse && request instanceof HttpServletRequest
- && tobagoConfig.isThemeCookie()) {
- CookieUtils.setThemeNameToCookie((HttpServletRequest) request, (HttpServletResponse) response, theme.getName());
- }
final String clientId = component.getClientId(facesContext);
final boolean productionMode = facesContext.isProjectStage(ProjectStage.Production);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/CookieUtils.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/CookieUtils.java
index bee602a..3694cc9 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/CookieUtils.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/CookieUtils.java
@@ -19,6 +19,7 @@
package org.apache.myfaces.tobago.internal.util;
+import org.apache.myfaces.tobago.context.Theme;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,8 +32,6 @@ public class CookieUtils {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- private static final String THEME_PARAMETER = "tobago.theme";
-
private static final int ONE_YEAR_IN_SECONDS = 365 * 24 * 60 * 60;
private CookieUtils() {
@@ -48,10 +47,10 @@ public class CookieUtils {
LOG.debug("cookie value ='{}'", cookie.getValue());
LOG.debug("cookie path ='{}'", cookie.getPath());
}
- if (THEME_PARAMETER.equals(cookie.getName())) {
+ if (Theme.THEME_KEY.equals(cookie.getName())) {
themeName = cookie.getValue();
if (LOG.isDebugEnabled()) {
- LOG.debug("theme from cookie {}='{}'", THEME_PARAMETER, themeName);
+ LOG.debug("theme from cookie {}='{}'", Theme.THEME_KEY, themeName);
}
break;
}
@@ -69,10 +68,10 @@ public class CookieUtils {
final Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (final Cookie cookie : cookies) {
- if (THEME_PARAMETER.equals(cookie.getName())) {
+ if (Theme.THEME_KEY.equals(cookie.getName())) {
if (found) {
if (LOG.isDebugEnabled()) {
- LOG.debug("Found more than one cookie {}, try to remove them...", THEME_PARAMETER);
+ LOG.debug("Found more than one cookie {}, try to remove them...", Theme.THEME_KEY);
}
cookie.setMaxAge(0);
} else {
@@ -97,7 +96,7 @@ public class CookieUtils {
}
}
if (!found) {
- final Cookie cookie = new Cookie(THEME_PARAMETER, themeName);
+ final Cookie cookie = new Cookie(Theme.THEME_KEY, themeName);
cookie.setPath(path);
cookie.setMaxAge(ONE_YEAR_IN_SECONDS);
cookie.setSecure(request.isSecure());
@@ -111,7 +110,7 @@ public class CookieUtils {
final Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (final Cookie cookie : cookies) {
- if (THEME_PARAMETER.equals(cookie.getName())) {
+ if (Theme.THEME_KEY.equals(cookie.getName())) {
cookie.setMaxAge(0);
cookie.setValue(null);
cookie.setSecure(request.isSecure());
diff --git a/tobago-core/src/main/resources/org/apache/myfaces/tobago/config/tobago-config-5.1.xsd b/tobago-core/src/main/resources/org/apache/myfaces/tobago/config/tobago-config-5.1.xsd
index 6b45ea9..7724ea3 100644
--- a/tobago-core/src/main/resources/org/apache/myfaces/tobago/config/tobago-config-5.1.xsd
+++ b/tobago-core/src/main/resources/org/apache/myfaces/tobago/config/tobago-config-5.1.xsd
@@ -239,6 +239,13 @@
</xs:documentation>
</xs:annotation>
</xs:element>
+ <xs:element name="theme-session" type="xs:boolean" minOccurs="0" maxOccurs="1" default="false">
+ <xs:annotation>
+ <xs:documentation>
+ Store the active theme the server session.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
</xs:sequence>
</xs:complexType>
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/TobagoConfigParserUnitTest.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/TobagoConfigParserUnitTest.java
index 296adff..33e08dd 100644
--- a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/TobagoConfigParserUnitTest.java
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/TobagoConfigParserUnitTest.java
@@ -197,4 +197,20 @@ public class TobagoConfigParserUnitTest {
Assertions.assertFalse(fragment.getThemeCookie());
}
+ @Test
+ public void testThemeSessionUndefined() throws Exception {
+ final URL url = getClass().getClassLoader().getResource("tobago-config-5.0.xml");
+ final TobagoConfigParser parser = new TobagoConfigParser();
+ final TobagoConfigFragment fragment = parser.parse(url);
+ Assertions.assertNull(fragment.getThemeSession());
+ }
+
+ @Test
+ public void testThemeSessionTrue() throws Exception {
+ final URL url = getClass().getClassLoader().getResource("tobago-config-5.1.xml");
+ final TobagoConfigParser parser = new TobagoConfigParser();
+ final TobagoConfigFragment fragment = parser.parse(url);
+ Assertions.assertTrue(fragment.getThemeSession());
+ }
+
}
diff --git a/tobago-core/src/test/resources/tobago-config-5.1.xml b/tobago-core/src/test/resources/tobago-config-5.1.xml
index 8f61e22..8ba26ba 100644
--- a/tobago-core/src/test/resources/tobago-config-5.1.xml
+++ b/tobago-core/src/test/resources/tobago-config-5.1.xml
@@ -39,6 +39,7 @@
<default-theme>my-theme-1</default-theme>
<supported-theme>my-theme-2</supported-theme>
<theme-cookie>false</theme-cookie>
+ <theme-session>true</theme-session>
</theme-config>
<create-session-secret>false</create-session-secret>
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/tobago-config.xml b/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/tobago-config.xml
index 7ce43c6..0f0c025 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/tobago-config.xml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/WEB-INF/tobago-config.xml
@@ -42,6 +42,8 @@
<supported-theme>speyside</supported-theme>
<supported-theme>roxborough</supported-theme>
<supported-theme>charlotteville</supported-theme>
+ <theme-cookie>false</theme-cookie>
+ <theme-session>true</theme-session>
</theme-config>
<!-- currently you need to switch this check off for quarkus -->