Package org.springframework.web.servlet.i18n

Source Code of org.springframework.web.servlet.i18n.CookieLocaleResolver

/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.web.servlet.i18n;

import java.util.Locale;
import java.util.TimeZone;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.i18n.LocaleContext;
import org.springframework.context.i18n.SimpleLocaleContext;
import org.springframework.context.i18n.TimeZoneAwareLocaleContext;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleContextResolver;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.util.CookieGenerator;
import org.springframework.web.util.WebUtils;

/**
* {@link LocaleResolver} implementation that uses a cookie sent back to the user
* in case of a custom setting, with a fallback to the specified default locale
* or the request's accept-header locale.
*
* <p>This is particularly useful for stateless applications without user sessions.
* The cookie may optionally contain an associated time zone value as well;
* alternatively, you may specify a default time zone.
*
* <p>Custom controllers can override the user's locale and time zone by calling
* {@code #setLocale(Context)} on the resolver, e.g. responding to a locale change
* request. As a more convenient alternative, consider using
* {@link org.springframework.web.servlet.support.RequestContext#changeLocale}.
*
* @author Juergen Hoeller
* @author Jean-Pierre Pawlak
* @since 27.02.2003
* @see #setDefaultLocale
* @see #setDefaultTimeZone
*/
public class CookieLocaleResolver extends CookieGenerator implements LocaleContextResolver {

  /**
   * The name of the request attribute that holds the Locale.
   * <p>Only used for overriding a cookie value if the locale has been
   * changed in the course of the current request!
   * <p>Use {@code RequestContext(Utils).getLocale()}
   * to retrieve the current locale in controllers or views.
   * @see org.springframework.web.servlet.support.RequestContext#getLocale
   * @see org.springframework.web.servlet.support.RequestContextUtils#getLocale
   */
  public static final String LOCALE_REQUEST_ATTRIBUTE_NAME = CookieLocaleResolver.class.getName() + ".LOCALE";

  /**
   * The name of the request attribute that holds the TimeZone.
   * <p>Only used for overriding a cookie value if the locale has been
   * changed in the course of the current request!
   * <p>Use {@code RequestContext(Utils).getTimeZone()}
   * to retrieve the current time zone in controllers or views.
   * @see org.springframework.web.servlet.support.RequestContext#getTimeZone
   * @see org.springframework.web.servlet.support.RequestContextUtils#getTimeZone
   */
  public static final String TIME_ZONE_REQUEST_ATTRIBUTE_NAME = CookieLocaleResolver.class.getName() + ".TIME_ZONE";

  /**
   * The default cookie name used if none is explicitly set.
   */
  public static final String DEFAULT_COOKIE_NAME = CookieLocaleResolver.class.getName() + ".LOCALE";


  private Locale defaultLocale;

  private TimeZone defaultTimeZone;


  /**
   * Create a new instance of the {@link CookieLocaleResolver} class
   * using the {@link #DEFAULT_COOKIE_NAME default cookie name}.
   */
  public CookieLocaleResolver() {
    setCookieName(DEFAULT_COOKIE_NAME);
  }

  /**
   * Set a fixed Locale that this resolver will return if no cookie found.
   */
  public void setDefaultLocale(Locale defaultLocale) {
    this.defaultLocale = defaultLocale;
  }

  /**
   * Return the fixed Locale that this resolver will return if no cookie found,
   * if any.
   */
  protected Locale getDefaultLocale() {
    return this.defaultLocale;
  }

  /**
   * Set a fixed TimeZone that this resolver will return if no cookie found.
   */
  public void setDefaultTimeZone(TimeZone defaultTimeZone) {
    this.defaultTimeZone = defaultTimeZone;
  }

  /**
   * Return the fixed TimeZone that this resolver will return if no cookie found,
   * if any.
   */
  protected TimeZone getDefaultTimeZone() {
    return this.defaultTimeZone;
  }


  @Override
  public Locale resolveLocale(HttpServletRequest request) {
    parseLocaleCookieIfNecessary(request);
    return (Locale) request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME);
  }

  @Override
  public LocaleContext resolveLocaleContext(final HttpServletRequest request) {
    parseLocaleCookieIfNecessary(request);
    return new TimeZoneAwareLocaleContext() {
      @Override
      public Locale getLocale() {
        return (Locale) request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME);
      }
      @Override
      public TimeZone getTimeZone() {
        return (TimeZone) request.getAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME);
      }
    };
  }

  private void parseLocaleCookieIfNecessary(HttpServletRequest request) {
    if (request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME) == null) {
      // Retrieve and parse cookie value.
      Cookie cookie = WebUtils.getCookie(request, getCookieName());
      Locale locale = null;
      TimeZone timeZone = null;
      if (cookie != null) {
        String value = cookie.getValue();
        String localePart = value;
        String timeZonePart = null;
        int spaceIndex = localePart.indexOf(' ');
        if (spaceIndex != -1) {
          localePart = value.substring(0, spaceIndex);
          timeZonePart = value.substring(spaceIndex + 1);
        }
        locale = (!"-".equals(localePart) ? StringUtils.parseLocaleString(localePart) : null);
        if (timeZonePart != null) {
          timeZone = StringUtils.parseTimeZoneString(timeZonePart);
        }
        if (logger.isDebugEnabled()) {
          logger.debug("Parsed cookie value [" + cookie.getValue() + "] into locale '" + locale +
              "'" + (timeZone != null ? " and time zone '" + timeZone.getID() + "'" : ""));
        }
      }
      request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME,
          (locale != null ? locale: determineDefaultLocale(request)));
      request.setAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME,
          (timeZone != null ? timeZone : determineDefaultTimeZone(request)));
    }
  }

  @Override
  public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
    setLocaleContext(request, response, (locale != null ? new SimpleLocaleContext(locale) : null));
  }

  @Override
  public void setLocaleContext(HttpServletRequest request, HttpServletResponse response, LocaleContext localeContext) {
    Locale locale = null;
    TimeZone timeZone = null;
    if (localeContext != null) {
      locale = localeContext.getLocale();
      if (localeContext instanceof TimeZoneAwareLocaleContext) {
        timeZone = ((TimeZoneAwareLocaleContext) localeContext).getTimeZone();
      }
      addCookie(response, (locale != null ? locale : "-") + (timeZone != null ? ' ' + timeZone.getID() : ""));
    }
    else {
      removeCookie(response);
    }
    request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME,
        (locale != null ? locale: determineDefaultLocale(request)));
    request.setAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME,
        (timeZone != null ? timeZone : determineDefaultTimeZone(request)));
  }


  /**
   * Determine the default locale for the given request,
   * Called if no locale cookie has been found.
   * <p>The default implementation returns the specified default locale,
   * if any, else falls back to the request's accept-header locale.
   * @param request the request to resolve the locale for
   * @return the default locale (never {@code null})
   * @see #setDefaultLocale
   * @see javax.servlet.http.HttpServletRequest#getLocale()
   */
  protected Locale determineDefaultLocale(HttpServletRequest request) {
    Locale defaultLocale = getDefaultLocale();
    if (defaultLocale == null) {
      defaultLocale = request.getLocale();
    }
    return defaultLocale;
  }

  /**
   * Determine the default time zone for the given request,
   * Called if no TimeZone cookie has been found.
   * <p>The default implementation returns the specified default time zone,
   * if any, or {@code null} otherwise.
   * @param request the request to resolve the time zone for
   * @return the default time zone (or {@code null} if none defined)
   * @see #setDefaultTimeZone
   */
  protected TimeZone determineDefaultTimeZone(HttpServletRequest request) {
    return getDefaultTimeZone();
  }

}
TOP

Related Classes of org.springframework.web.servlet.i18n.CookieLocaleResolver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.