001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.servlet.theme; 018 019import javax.servlet.http.Cookie; 020import javax.servlet.http.HttpServletRequest; 021import javax.servlet.http.HttpServletResponse; 022 023import org.springframework.lang.Nullable; 024import org.springframework.util.Assert; 025import org.springframework.util.StringUtils; 026import org.springframework.web.servlet.ThemeResolver; 027import org.springframework.web.util.CookieGenerator; 028import org.springframework.web.util.WebUtils; 029 030/** 031 * {@link ThemeResolver} implementation that uses a cookie sent back to the user 032 * in case of a custom setting, with a fallback to the default theme. 033 * This is particularly useful for stateless applications without user sessions. 034 * 035 * <p>Custom controllers can thus override the user's theme by calling 036 * {@code setThemeName}, e.g. responding to a certain theme change request. 037 * 038 * @author Jean-Pierre Pawlak 039 * @author Juergen Hoeller 040 * @since 17.06.2003 041 * @see #setThemeName 042 */ 043public class CookieThemeResolver extends CookieGenerator implements ThemeResolver { 044 045 /** 046 * The default theme name used if no alternative is provided. 047 */ 048 public static final String ORIGINAL_DEFAULT_THEME_NAME = "theme"; 049 050 /** 051 * Name of the request attribute that holds the theme name. Only used 052 * for overriding a cookie value if the theme has been changed in the 053 * course of the current request! Use RequestContext.getTheme() to 054 * retrieve the current theme in controllers or views. 055 * @see org.springframework.web.servlet.support.RequestContext#getTheme 056 */ 057 public static final String THEME_REQUEST_ATTRIBUTE_NAME = CookieThemeResolver.class.getName() + ".THEME"; 058 059 /** 060 * The default name of the cookie that holds the theme name. 061 */ 062 public static final String DEFAULT_COOKIE_NAME = CookieThemeResolver.class.getName() + ".THEME"; 063 064 065 private String defaultThemeName = ORIGINAL_DEFAULT_THEME_NAME; 066 067 068 public CookieThemeResolver() { 069 setCookieName(DEFAULT_COOKIE_NAME); 070 } 071 072 073 /** 074 * Set the name of the default theme. 075 */ 076 public void setDefaultThemeName(String defaultThemeName) { 077 this.defaultThemeName = defaultThemeName; 078 } 079 080 /** 081 * Return the name of the default theme. 082 */ 083 public String getDefaultThemeName() { 084 return this.defaultThemeName; 085 } 086 087 088 @Override 089 public String resolveThemeName(HttpServletRequest request) { 090 // Check request for preparsed or preset theme. 091 String themeName = (String) request.getAttribute(THEME_REQUEST_ATTRIBUTE_NAME); 092 if (themeName != null) { 093 return themeName; 094 } 095 096 // Retrieve cookie value from request. 097 String cookieName = getCookieName(); 098 if (cookieName != null) { 099 Cookie cookie = WebUtils.getCookie(request, cookieName); 100 if (cookie != null) { 101 String value = cookie.getValue(); 102 if (StringUtils.hasText(value)) { 103 themeName = value; 104 } 105 } 106 } 107 108 // Fall back to default theme. 109 if (themeName == null) { 110 themeName = getDefaultThemeName(); 111 } 112 request.setAttribute(THEME_REQUEST_ATTRIBUTE_NAME, themeName); 113 return themeName; 114 } 115 116 @Override 117 public void setThemeName( 118 HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable String themeName) { 119 120 Assert.notNull(response, "HttpServletResponse is required for CookieThemeResolver"); 121 122 if (StringUtils.hasText(themeName)) { 123 // Set request attribute and add cookie. 124 request.setAttribute(THEME_REQUEST_ATTRIBUTE_NAME, themeName); 125 addCookie(response, themeName); 126 } 127 else { 128 // Set request attribute to fallback theme and remove cookie. 129 request.setAttribute(THEME_REQUEST_ATTRIBUTE_NAME, getDefaultThemeName()); 130 removeCookie(response); 131 } 132 } 133 134}