/** * Return the default locale to use if no explicit locale has been given. * <p>The default implementation returns the default locale passed into the * corresponding constructor, or LocaleContextHolder's locale as fallback. * Can be overridden in subclasses. * @see #MessageSourceAccessor(org.springframework.context.MessageSource, java.util.Locale) * @see org.springframework.context.i18n.LocaleContextHolder#getLocale() */ protected Locale getDefaultLocale() { return (this.defaultLocale != null ? this.defaultLocale : LocaleContextHolder.getLocale()); }
/** * Return the Locale associated with the current thread, if any, * or the system default Locale otherwise. This is effectively a * replacement for {@link java.util.Locale#getDefault()}, * able to optionally respect a user-level Locale setting. * <p>Note: This method has a fallback to the shared default Locale, * either at the framework level or at the JVM-wide system level. * If you'd like to check for the raw LocaleContext content * (which may indicate no specific locale through {@code null}, use * {@link #getLocaleContext()} and call {@link LocaleContext#getLocale()} * @return the current Locale, or the system default Locale if no * specific Locale has been associated with the current thread * @see #getLocaleContext() * @see LocaleContext#getLocale() * @see #setDefaultLocale(Locale) * @see java.util.Locale#getDefault() */ public static Locale getLocale() { return getLocale(getLocaleContext()); }
/** * Return the default locale to use if no explicit locale has been given. * <p>The default implementation returns the default locale passed into the * corresponding constructor, or LocaleContextHolder's locale as fallback. * Can be overridden in subclasses. * @see #MessageSourceAccessor(org.springframework.context.MessageSource, java.util.Locale) * @see org.springframework.context.i18n.LocaleContextHolder#getLocale() */ protected Locale getDefaultLocale() { return (this.defaultLocale != null ? this.defaultLocale : LocaleContextHolder.getLocale()); }
@Test public void testSetTimeZoneAwareLocaleContext() { LocaleContext lc = new SimpleTimeZoneAwareLocaleContext(Locale.GERMANY, TimeZone.getTimeZone("GMT+1")); LocaleContextHolder.setLocaleContext(lc); assertSame(lc, LocaleContextHolder.getLocaleContext()); assertEquals(Locale.GERMANY, LocaleContextHolder.getLocale()); assertEquals(TimeZone.getTimeZone("GMT+1"), LocaleContextHolder.getTimeZone()); LocaleContextHolder.resetLocaleContext(); assertNull(LocaleContextHolder.getLocaleContext()); assertEquals(Locale.getDefault(), LocaleContextHolder.getLocale()); assertEquals(TimeZone.getDefault(), LocaleContextHolder.getTimeZone()); }
@Override public String interpolate(String message, Context context) { return this.targetInterpolator.interpolate(message, context, LocaleContextHolder.getLocale()); }
@Test public void testSetLocale() { LocaleContextHolder.setLocale(Locale.GERMAN); assertEquals(Locale.GERMAN, LocaleContextHolder.getLocale()); assertEquals(TimeZone.getDefault(), LocaleContextHolder.getTimeZone()); assertFalse(LocaleContextHolder.getLocaleContext() instanceof TimeZoneAwareLocaleContext); assertEquals(Locale.GERMAN, LocaleContextHolder.getLocaleContext().getLocale()); LocaleContextHolder.setLocale(Locale.GERMANY); assertEquals(Locale.GERMANY, LocaleContextHolder.getLocale()); assertEquals(TimeZone.getDefault(), LocaleContextHolder.getTimeZone()); assertFalse(LocaleContextHolder.getLocaleContext() instanceof TimeZoneAwareLocaleContext); assertEquals(Locale.GERMANY, LocaleContextHolder.getLocaleContext().getLocale()); LocaleContextHolder.setLocale(null); assertNull(LocaleContextHolder.getLocaleContext()); assertEquals(Locale.getDefault(), LocaleContextHolder.getLocale()); assertEquals(TimeZone.getDefault(), LocaleContextHolder.getTimeZone()); LocaleContextHolder.setDefaultLocale(Locale.GERMAN); assertEquals(Locale.GERMAN, LocaleContextHolder.getLocale()); LocaleContextHolder.setDefaultLocale(null); assertEquals(Locale.getDefault(), LocaleContextHolder.getLocale()); }
/** * Apply the resolved status code and reason to the response. * <p>The default implementation sends a response error using * {@link HttpServletResponse#sendError(int)} or * {@link HttpServletResponse#sendError(int, String)} if there is a reason * and then returns an empty ModelAndView. * @param statusCode the HTTP status code * @param reason the associated reason (may be {@code null} or empty) * @param response current HTTP response * @since 5.0 */ protected ModelAndView applyStatusAndReason(int statusCode, @Nullable String reason, HttpServletResponse response) throws IOException { if (!StringUtils.hasLength(reason)) { response.sendError(statusCode); } else { String resolvedReason = (this.messageSource != null ? this.messageSource.getMessage(reason, null, reason, LocaleContextHolder.getLocale()) : reason); response.sendError(statusCode, resolvedReason); } return new ModelAndView(); }
@Test public void testSetLocaleContext() { LocaleContext lc = new SimpleLocaleContext(Locale.GERMAN); LocaleContextHolder.setLocaleContext(lc); assertSame(lc, LocaleContextHolder.getLocaleContext()); assertEquals(Locale.GERMAN, LocaleContextHolder.getLocale()); assertEquals(TimeZone.getDefault(), LocaleContextHolder.getTimeZone()); lc = new SimpleLocaleContext(Locale.GERMANY); LocaleContextHolder.setLocaleContext(lc); assertSame(lc, LocaleContextHolder.getLocaleContext()); assertEquals(Locale.GERMANY, LocaleContextHolder.getLocale()); assertEquals(TimeZone.getDefault(), LocaleContextHolder.getTimeZone()); LocaleContextHolder.resetLocaleContext(); assertNull(LocaleContextHolder.getLocaleContext()); assertEquals(Locale.getDefault(), LocaleContextHolder.getLocale()); assertEquals(TimeZone.getDefault(), LocaleContextHolder.getTimeZone()); }
@Override public String interpolate(String message, Context context) { return this.targetInterpolator.interpolate(message, context, LocaleContextHolder.getLocale()); }
@Test public void testSetTimeZone() { LocaleContextHolder.setTimeZone(TimeZone.getTimeZone("GMT+1")); assertEquals(Locale.getDefault(), LocaleContextHolder.getLocale()); assertEquals(TimeZone.getTimeZone("GMT+1"), LocaleContextHolder.getTimeZone()); assertTrue(LocaleContextHolder.getLocaleContext() instanceof TimeZoneAwareLocaleContext); assertNull(LocaleContextHolder.getLocaleContext().getLocale()); assertEquals(TimeZone.getTimeZone("GMT+1"), ((TimeZoneAwareLocaleContext) LocaleContextHolder.getLocaleContext()).getTimeZone()); LocaleContextHolder.setTimeZone(TimeZone.getTimeZone("GMT+2")); assertEquals(Locale.getDefault(), LocaleContextHolder.getLocale()); assertEquals(TimeZone.getTimeZone("GMT+2"), LocaleContextHolder.getTimeZone()); assertTrue(LocaleContextHolder.getLocaleContext() instanceof TimeZoneAwareLocaleContext); assertNull(LocaleContextHolder.getLocaleContext().getLocale()); assertEquals(TimeZone.getTimeZone("GMT+2"), ((TimeZoneAwareLocaleContext) LocaleContextHolder.getLocaleContext()).getTimeZone()); LocaleContextHolder.setTimeZone(null); assertNull(LocaleContextHolder.getLocaleContext()); assertEquals(Locale.getDefault(), LocaleContextHolder.getLocale()); assertEquals(TimeZone.getDefault(), LocaleContextHolder.getTimeZone()); LocaleContextHolder.setDefaultTimeZone(TimeZone.getTimeZone("GMT+1")); assertEquals(TimeZone.getTimeZone("GMT+1"), LocaleContextHolder.getTimeZone()); LocaleContextHolder.setDefaultTimeZone(null); assertEquals(TimeZone.getDefault(), LocaleContextHolder.getTimeZone()); }
@Override public String getAsText() { Object value = getValue(); return (value != null ? this.formatter.print(value, LocaleContextHolder.getLocale()) : ""); }
@Override @SuppressWarnings("unchecked") public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (!sourceType.isAssignableTo(this.printerObjectType)) { source = this.conversionService.convert(source, sourceType, this.printerObjectType); } if (source == null) { return ""; } return this.printer.print(source, LocaleContextHolder.getLocale()); }
@Override public void setAsText(String text) throws IllegalArgumentException { if (StringUtils.hasText(text)) { try { setValue(this.formatter.parse(text, LocaleContextHolder.getLocale())); } catch (IllegalArgumentException ex) { throw ex; } catch (Throwable ex) { throw new IllegalArgumentException("Parse attempt failed for value [" + text + "]", ex); } } else { setValue(null); } }
@Override @Nullable public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { String text = (String) source; if (!StringUtils.hasText(text)) { return null; } Object result; try { result = this.parser.parse(text, LocaleContextHolder.getLocale()); } catch (IllegalArgumentException ex) { throw ex; } catch (Throwable ex) { throw new IllegalArgumentException("Parse attempt failed for value [" + text + "]", ex); } TypeDescriptor resultType = TypeDescriptor.valueOf(result.getClass()); if (!resultType.isAssignableTo(targetType)) { result = this.conversionService.convert(result, resultType, targetType); } return result; }
@Override public String getAsText() { Object value = getValue(); return (value != null ? this.formatter.print(value, LocaleContextHolder.getLocale()) : ""); }
@Test public void testJodaTimePatternsForStyle() { System.out.println(org.joda.time.format.DateTimeFormat.patternForStyle("SS", LocaleContextHolder.getLocale())); System.out.println(org.joda.time.format.DateTimeFormat.patternForStyle("MM", LocaleContextHolder.getLocale())); System.out.println(org.joda.time.format.DateTimeFormat.patternForStyle("LL", LocaleContextHolder.getLocale())); System.out.println(org.joda.time.format.DateTimeFormat.patternForStyle("FF", LocaleContextHolder.getLocale())); }
@Override @SuppressWarnings("unchecked") public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (!sourceType.isAssignableTo(this.printerObjectType)) { source = this.conversionService.convert(source, sourceType, this.printerObjectType); } if (source == null) { return ""; } return this.printer.print(source, LocaleContextHolder.getLocale()); }
/** * Resolve a template from the given template path. * <p>The default implementation uses the Locale associated with the current request, * as obtained through {@link org.springframework.context.i18n.LocaleContextHolder LocaleContextHolder}, * to find the template file. Effectively the locale configured at the engine level is ignored. * @see LocaleContextHolder * @see #setLocale */ protected URL resolveTemplate(ClassLoader classLoader, String templatePath) throws IOException { MarkupTemplateEngine.TemplateResource resource = MarkupTemplateEngine.TemplateResource.parse(templatePath); Locale locale = LocaleContextHolder.getLocale(); URL url = classLoader.getResource(resource.withLocale(StringUtils.replace(locale.toString(), "-", "_")).toString()); if (url == null) { url = classLoader.getResource(resource.withLocale(locale.getLanguage()).toString()); } if (url == null) { url = classLoader.getResource(resource.withLocale(null).toString()); } if (url == null) { throw new IOException("Unable to load template:" + templatePath); } return url; }
@Override protected Mono<Void> writeToInternal(ServerWebExchange exchange, Context context) { MediaType contentType = exchange.getResponse().getHeaders().getContentType(); Locale locale = LocaleContextHolder.getLocale(exchange.getLocaleContext()); Stream<ViewResolver> viewResolverStream = context.viewResolvers().stream(); return Flux.fromStream(viewResolverStream) .concatMap(viewResolver -> viewResolver.resolveViewName(name(), locale)) .next() .switchIfEmpty(Mono.error(() -> new IllegalArgumentException("Could not resolve view with name '" + name() + "'"))) .flatMap(view -> { List<MediaType> mediaTypes = view.getSupportedMediaTypes(); return view.render(model(), contentType == null && !mediaTypes.isEmpty() ? mediaTypes.get(0) : contentType, exchange); }); }
@Override protected Mono<Void> renderInternal(Map<String, Object> renderAttributes, @Nullable MediaType contentType, ServerWebExchange exchange) { // Expose all standard FreeMarker hash models. SimpleHash freeMarkerModel = getTemplateModel(renderAttributes, exchange); if (logger.isDebugEnabled()) { logger.debug(exchange.getLogPrefix() + "Rendering [" + getUrl() + "]"); } Locale locale = LocaleContextHolder.getLocale(exchange.getLocaleContext()); DataBuffer dataBuffer = exchange.getResponse().bufferFactory().allocateBuffer(); try { Charset charset = getCharset(contentType); Writer writer = new OutputStreamWriter(dataBuffer.asOutputStream(), charset); getTemplate(locale).process(freeMarkerModel, writer); } catch (IOException ex) { DataBufferUtils.release(dataBuffer); String message = "Could not load FreeMarker template for URL [" + getUrl() + "]"; return Mono.error(new IllegalStateException(message, ex)); } catch (Throwable ex) { DataBufferUtils.release(dataBuffer); return Mono.error(ex); } return exchange.getResponse().writeWith(Flux.just(dataBuffer)); }