001/*
002 * Copyright 2002-2013 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.util.StringUtils;
024import org.springframework.web.servlet.ThemeResolver;
025import org.springframework.web.util.CookieGenerator;
026import org.springframework.web.util.WebUtils;
027
028/**
029 * {@link ThemeResolver} implementation that uses a cookie sent back to the user
030 * in case of a custom setting, with a fallback to the default theme.
031 * This is particularly useful for stateless applications without user sessions.
032 *
033 * <p>Custom controllers can thus override the user's theme by calling
034 * {@code setThemeName}, e.g. responding to a certain theme change request.
035 *
036 * @author Jean-Pierre Pawlak
037 * @author Juergen Hoeller
038 * @since 17.06.2003
039 * @see #setThemeName
040 */
041public class CookieThemeResolver extends CookieGenerator implements ThemeResolver {
042
043        public final static String ORIGINAL_DEFAULT_THEME_NAME = "theme";
044
045        /**
046         * Name of the request attribute that holds the theme name. Only used
047         * for overriding a cookie value if the theme has been changed in the
048         * course of the current request! Use RequestContext.getTheme() to
049         * retrieve the current theme in controllers or views.
050         * @see org.springframework.web.servlet.support.RequestContext#getTheme
051         */
052        public static final String THEME_REQUEST_ATTRIBUTE_NAME = CookieThemeResolver.class.getName() + ".THEME";
053
054        public static final String DEFAULT_COOKIE_NAME = CookieThemeResolver.class.getName() + ".THEME";
055
056
057        private String defaultThemeName = ORIGINAL_DEFAULT_THEME_NAME;
058
059
060        public CookieThemeResolver() {
061                setCookieName(DEFAULT_COOKIE_NAME);
062        }
063
064
065        /**
066         * Set the name of the default theme.
067         */
068        public void setDefaultThemeName(String defaultThemeName) {
069                this.defaultThemeName = defaultThemeName;
070        }
071
072        /**
073         * Return the name of the default theme.
074         */
075        public String getDefaultThemeName() {
076                return defaultThemeName;
077        }
078
079
080        @Override
081        public String resolveThemeName(HttpServletRequest request) {
082                // Check request for preparsed or preset theme.
083                String themeName = (String) request.getAttribute(THEME_REQUEST_ATTRIBUTE_NAME);
084                if (themeName != null) {
085                        return themeName;
086                }
087
088                // Retrieve cookie value from request.
089                Cookie cookie = WebUtils.getCookie(request, getCookieName());
090                if (cookie != null) {
091                        String value = cookie.getValue();
092                        if (StringUtils.hasText(value)) {
093                                themeName = value;
094                        }
095                }
096
097                // Fall back to default theme.
098                if (themeName == null) {
099                        themeName = getDefaultThemeName();
100                }
101                request.setAttribute(THEME_REQUEST_ATTRIBUTE_NAME, themeName);
102                return themeName;
103        }
104
105        @Override
106        public void setThemeName(HttpServletRequest request, HttpServletResponse response, String themeName) {
107                if (StringUtils.hasText(themeName)) {
108                        // Set request attribute and add cookie.
109                        request.setAttribute(THEME_REQUEST_ATTRIBUTE_NAME, themeName);
110                        addCookie(response, themeName);
111                }
112                else {
113                        // Set request attribute to fallback theme and remove cookie.
114                        request.setAttribute(THEME_REQUEST_ATTRIBUTE_NAME, getDefaultThemeName());
115                        removeCookie(response);
116                }
117        }
118
119}