001: /*
002: * Copyright 2002-2007 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: * http://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:
017: package org.springframework.web.servlet.i18n;
018:
019: import java.util.Locale;
020:
021: import javax.servlet.http.Cookie;
022: import javax.servlet.http.HttpServletRequest;
023: import javax.servlet.http.HttpServletResponse;
024:
025: import org.springframework.util.StringUtils;
026: import org.springframework.web.servlet.LocaleResolver;
027: import org.springframework.web.util.CookieGenerator;
028: import org.springframework.web.util.WebUtils;
029:
030: /**
031: * {@link LocaleResolver} implementation that uses a cookie sent back to the user
032: * in case of a custom setting, with a fallback to the specified default locale
033: * or the request's accept-header locale.
034: *
035: * <p>This is particularly useful for stateless applications without user sessions.
036: *
037: * <p>Custom controllers can thus override the user's locale by calling
038: * {@link #setLocale(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.util.Locale)},
039: * for example responding to a certain locale change request.
040: *
041: * @author Juergen Hoeller
042: * @author Jean-Pierre Pawlak
043: * @since 27.02.2003
044: * @see #setDefaultLocale
045: * @see #setLocale
046: */
047: public class CookieLocaleResolver extends CookieGenerator implements
048: LocaleResolver {
049:
050: /**
051: * The name of the request attribute that holds the locale.
052: * <p>Only used for overriding a cookie value if the locale has been
053: * changed in the course of the current request! Use
054: * {@link org.springframework.web.servlet.support.RequestContext#getLocale}
055: * to retrieve the current locale in controllers or views.
056: * @see org.springframework.web.servlet.support.RequestContext#getLocale
057: */
058: public static final String LOCALE_REQUEST_ATTRIBUTE_NAME = CookieLocaleResolver.class
059: .getName()
060: + ".LOCALE";
061:
062: /**
063: * The default cookie name used if none is explicitly set.
064: */
065: public static final String DEFAULT_COOKIE_NAME = CookieLocaleResolver.class
066: .getName()
067: + ".LOCALE";
068:
069: private Locale defaultLocale;
070:
071: /**
072: * Creates a new instance of the {@link CookieLocaleResolver} class
073: * using the {@link #DEFAULT_COOKIE_NAME default cookie name}.
074: */
075: public CookieLocaleResolver() {
076: setCookieName(DEFAULT_COOKIE_NAME);
077: }
078:
079: /**
080: * Set a fixed Locale that this resolver will return if no cookie found.
081: */
082: public void setDefaultLocale(Locale defaultLocale) {
083: this .defaultLocale = defaultLocale;
084: }
085:
086: /**
087: * Return the fixed Locale that this resolver will return if no cookie found,
088: * if any.
089: */
090: protected Locale getDefaultLocale() {
091: return this .defaultLocale;
092: }
093:
094: public Locale resolveLocale(HttpServletRequest request) {
095: // Check request for pre-parsed or preset locale.
096: Locale locale = (Locale) request
097: .getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME);
098: if (locale != null) {
099: return locale;
100: }
101:
102: // Retrieve and parse cookie value.
103: Cookie cookie = WebUtils.getCookie(request, getCookieName());
104: if (cookie != null) {
105: locale = StringUtils.parseLocaleString(cookie.getValue());
106: if (logger.isDebugEnabled()) {
107: logger.debug("Parsed cookie value ["
108: + cookie.getValue() + "] into locale '"
109: + locale + "'");
110: }
111: if (locale != null) {
112: request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME,
113: locale);
114: return locale;
115: }
116: }
117:
118: return determineDefaultLocale(request);
119: }
120:
121: public void setLocale(HttpServletRequest request,
122: HttpServletResponse response, Locale locale) {
123: if (locale != null) {
124: // Set request attribute and add cookie.
125: request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME, locale);
126: addCookie(response, locale.toString());
127: } else {
128: // Set request attribute to fallback locale and remove cookie.
129: request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME,
130: determineDefaultLocale(request));
131: removeCookie(response);
132: }
133: }
134:
135: /**
136: * Determine the default locale for the given request,
137: * Called if no locale cookie has been found.
138: * <p>The default implementation returns the specified default locale,
139: * if any, else falls back to the request's accept-header locale.
140: * @param request the request to resolve the locale for
141: * @return the default locale (never <code>null</code>)
142: * @see #setDefaultLocale
143: * @see javax.servlet.http.HttpServletRequest#getLocale()
144: */
145: protected Locale determineDefaultLocale(HttpServletRequest request) {
146: Locale defaultLocale = getDefaultLocale();
147: if (defaultLocale == null) {
148: defaultLocale = request.getLocale();
149: }
150: return defaultLocale;
151: }
152:
153: }
|